c++ - 通过查看程序集比较按值传递与按引用传递的性能

标签 c++ gcc assembly visual-c++ clang

我想测试一个函数以验证哪个更快,按值传递还是按引用传递

这是我的测试用例:https://godbolt.org/g/cjaEx3

代码:

struct Vec4f
{
  float val[4];
};


Vec4f suma(const Vec4f& a, const Vec4f& b)
{
  return {a.val[0] + b.val[0], 
          a.val[1] + b.val[1],
          a.val[2] + b.val[2],
          a.val[3] + b.val[3]};
}

Vec4f sumb(Vec4f a, Vec4f b)
{
  return {a.val[0] + b.val[0], 
          a.val[1] + b.val[1],
          a.val[2] + b.val[2],
          a.val[3] + b.val[3]};
}

使用 -O3 -std=c++14 在 x86-64 clang 上的程序集输出:

suma(Vec4f const&, Vec4f const&):                     # @suma(Vec4f const&, Vec4f const&)
        movq    xmm1, qword ptr [rdi]   # xmm1 = mem[0],zero
        movq    xmm0, qword ptr [rsi]   # xmm0 = mem[0],zero
        addps   xmm0, xmm1
        movq    xmm2, qword ptr [rdi + 8] # xmm2 = mem[0],zero
        movq    xmm1, qword ptr [rsi + 8] # xmm1 = mem[0],zero
        addps   xmm1, xmm2
        ret

sumb(Vec4f, Vec4f):                        # @sumb(Vec4f, Vec4f)
        addps   xmm0, xmm2
        addps   xmm1, xmm3
        ret

事实证明,在 gcc、clang 和 msvc 上,在这种特殊情况下,按值传递会产生更少的汇编。

我的问题是:

  1. 比较 assembly 线数量通常是比较此类简单功能性能的良好启发式方法吗?

而且我不太了解汇编输出

  1. 你能解释一下 sumasumb 函数的汇编输出吗?

有趣的是,如果我将 Vec4f 改为具有 float val[40],这两个函数会产生相同的汇编输出。所以,

  1. 初始组装差异的原因是什么?

最佳答案

1) 不。并非所有指令的执行时间都相同,一旦需要访问内存,就会有很大的延迟。

2) 和 3)。 suma 需要将ab 的内容加载到适当的寄存器中。在 sumb 中,这些值被传递给寄存器中已有的函数。在某些情况下,suma 中的寄存器加载将由 sumb 的调用者完成。在其他情况下,值可能已经在寄存器中,suma 调用者首先需要将这些值存储在内存中,以便它可以创建对它们的引用。

当你使用 float val[40] 时,它超出了寄存器传递值的能力,所以这两个函数都需要先从内存中加载数据(在 suma 中) ,通过取消引用引用;在 sumb 中,通过从堆栈加载值)。

关于c++ - 通过查看程序集比较按值传递与按引用传递的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45135688/

相关文章:

c++ - 将数据写入内存而不是文件时,avformat_write_header() 不起作用

c - 有时单利计划中会出现错误的值

c++ - gcc 和 g++ 错误 : error trying to exec 'cc1plus' : execvp: No such file or directory

assembly - 为什么 linux nasm 即使没有 16 字节堆栈对齐也能工作

c++ - 重绘窗口问题

c++ - 如何使用函数指针作为类中的参数

c++ - 使用静态初始化的副作用进行一次性初始化

c++ - 为什么 gcc 和 clang 允许我构造一个抽象类?

assembly - ARM cortex m4 DSP 代码上的快速 1 位透明 blit

assembly - = 和 := 之间的区别