fastcall调用约定真的比其他调用约定(如cdecl)更快吗?是否有任何基准测试可以显示调用约定如何影响性能?
fastcall调用约定真的比其他调用约定(如cdecl)更快吗?是否有任何基准测试可以显示调用约定如何影响性能?
这取决于平台。例如,对于Xenon PowerPC,由于在堆栈上传递数据存在负载-命中-存储问题,它可能存在数量级的差异。根据我的实证计时,cdecl
函数的开销大约为45个周期,而fastcall
则为约4个周期。
对于乱序执行的x86(英特尔和AMD),影响可能会小得多,因为所有寄存器都被阴影化和重命名了。
真正的答案是您需要在自己关心的特定平台上进行基准测试。
fastcall调用约定真的比其他调用约定(例如cdecl)更快吗?
我认为微软在x86和x64上的实现方式是将前两个参数通过寄存器传递,而不是通过堆栈。
由于它通常可以节省至少四次内存访问,因此它通常更快。但是,如果函数缺乏寄存器并且很可能将它们写入本地变量到堆栈中,那么不太可能会有显着的增加。
x86_64
mingw-w64
C++11上,__attribute__((fastcall))
编译并生成了一个与fastcall
兼容的函数。此外,架构无法标准化调用约定,因为它们是编译器特性。 - Kotauskas调用约定(至少在x86上)对于速度并没有太大影响。在Windows中,_stdcall
成为默认值是因为与_cdecl
相比通常会导致代码大小更小,这对于非平凡程序产生了实质性的结果。_fastcall
不是默认值,因为它所产生的区别远远没有那么明显。虽然通过寄存器传递参数可以节省时间,但是在函数体内部效率较低(正如Anon.先前所述)。如果被调用的函数立即需要将所有内容溢出到内存中进行计算,则通过寄存器传递参数没有任何优势。
然而,我们可以整天说理论性的想法——针对正确答案来测试您的代码。 _fastcall
在某些情况下会更快,而在其他情况下则会更慢。
对于现代的x86架构,没有快速调用(fastcall)的空间。在L1缓存和内联之间没有位置。
.cpp
文件中定义了许多小函数而不是.h
的项目,但它仍然很有用。 - Peter Cordes