将值作为函数参数传递vs计算两次?

use*_*112 5 c c++ linux optimization performance

我记得Agner Fog的优秀指南,64位Linux可以通过寄存器传递6个整数函数参数:

http://www.agner.org/optimize/optimizing_cpp.pdf

(第8页)

我有以下功能:

void x(signed int a, uint b, char c, unit d, uint e, signed short f);
Run Code Online (Sandbox Code Playgroud)

我需要传递一个额外的无符号短参数,总共会产生7个参数.但是,我实际上可以从现有的6中得到第7个值.

所以我的问题是以下哪项是更好的性能实践:

  • 将已计算的值作为第64个参数传递给64位Linux
  • 不传递已经计算的值,而是使用现有的6个参数之一再次计算它.

有问题的操作是一个简单的位移:

unsigned short g = c & 1;
Run Code Online (Sandbox Code Playgroud)

不完全理解x86汇编程序我不太确定寄存器是多么珍贵以及将值重新计算为局部变量是否更好,而不是通过函数调用作为参数传递?

我的信念是,计算两次值会更好,因为它是一个简单的1 CPU循环任务.

编辑我知道我可以对此进行分析 - 但我也想了解两种方法下的情况.有第7个参数这是否意味着涉及缓存/内存,而不是寄存器?

Bas*_*tch 4

传递参数的机器约定称为应用程序二进制接口(或 ABI),对于 Linux x86-64,在x86-64 ABI 规范中进行了描述。另请参阅x86 调用约定wiki 页面。

在您的情况下,可能不值得c & 1作为附加参数传递(因为第 7参数是在堆栈上传递的)。

不要忘记,当前的处理器核心(在台式机或笔记本电脑上)通常执行无序执行并且是超标量,因此该c & 1操作可以与其他操作并行完成,并且可能“不产生任何成本”。

但将这种微观优化留给编译器。如果您非常关心性能,请使用最新的 GCC 4.8 编译器进行gcc-4.8 -O3 -flto编译和链接(即启用链接时优化)。

顺便说一句,缓存性能比此类微优化更重要。单个高速缓存未命中可能花费与数百个CPU机器指令相同的时间(例如250纳秒)。据传当前的 CPU 大部分时间都在等待缓存。您可能想要添加一些明确的(且明智的)调用__builtin_prefetch(请参阅此问题此答案)。但是添加太多这些预取会减慢您的代码速度。

最后,代码的可读性和可维护性应该比原始性能更重要!