很多文献都谈到使用内联函数来“避免函数调用的开销”。然而,我还没有看到可量化的数据。函数调用的实际开销是多少?也就是说,我们通过内联函数实现了什么样的性能提升?
发布于 2008-09-28 02:14:31
在大多数架构上,开销包括将所有(或部分或无)寄存器保存到堆栈,将函数参数推入堆栈(或将它们放入寄存器中),递增堆栈指针并跳转到新代码的开头。然后,当函数完成时,您必须从堆栈恢复寄存器。This webpage描述了各种调用约定所涉及的内容。
大多数C++编译器现在都足够智能,可以为您内联函数。inline关键字只是对编译器的一个提示。有些人甚至会跨翻译单元进行内联,他们认为这是有帮助的。
发布于 2016-08-07 22:31:27
我针对一个简单的增量函数做了一个简单的基准测试:
inc.c:
typedef unsigned long ulong;
ulong inc(ulong x){
return x+1;
}main.c
#include <stdio.h>
#include <stdlib.h>
typedef unsigned long ulong;
#ifdef EXTERN
ulong inc(ulong);
#else
static inline ulong inc(ulong x){
return x+1;
}
#endif
int main(int argc, char** argv){
if (argc < 1+1)
return 1;
ulong i, sum = 0, cnt;
cnt = atoi(argv[1]);
for(i=0;i<cnt;i++){
sum+=inc(i);
}
printf("%lu\n", sum);
return 0;
}在我的英特尔(R)酷睿(TM) i5处理器M430@2.27 gave上运行了十亿次,给我带来了:
(适用于的version
(它似乎波动高达0.2,但我太懒了,不去计算适当的标准差,也不关心它们)
这表明此计算机上函数调用的开销约为3纳秒
我在它上测量的最快速度大约是0.3 to,所以这表明函数调用的成本大约是9原语操作,这是非常简单的。
对于通过PLT调用的函数(共享库中的函数),此开销增加了大约另一个2ns (每次调用的总时间约为6ns)。
发布于 2008-09-28 02:53:14
这就是技术和实际的答案。实际的答案是,它永远不会有问题,在非常罕见的情况下,您知道的唯一方法就是通过实际的概要测试。
由于编译器优化,您的文献中提到的技术答案通常是无关的。但如果你仍然感兴趣,Josh对此有很好的描述。
至于“百分比”,你必须知道函数本身有多昂贵。在被调用函数的开销之外,没有百分比,因为您正在与零成本操作进行比较。对于内联代码,没有任何开销,处理器只是移动到下一条指令。inling的缺点是更大的代码长度,这以一种不同于堆栈构建/拆卸成本的方式显示了它的成本。
https://stackoverflow.com/questions/144993
复制相似问题