在C++中,第一个函数调用是否有开销



我在C++中尝试分析某些东西,我遇到了一个非常奇怪的事情,我对此没有任何解释。基本上,在main中进行的第一个函数调用总是比任何后续调用花费更长的时间。这让我觉得第一个函数调用有一些开销。我不确定这些开销会来自什么,所以如果有人对为什么会发生这种情况有任何见解,我将不胜感激。此外,我正在使用Clang++

显示这一点的一个简单代码片段是

#include <iostream>
#include <time.h>
const int size = 1000000;
using namespace std;
void foo() {
int arr[size];
for(int i = 0; i < size; i++){
arr[i] = 1;
}
}
int main(){
for(int i = 0; i < 10; i++){
clock_t t = clock();
foo();
t = clock() - t;
cout << "cycles: " << t << endl;
}
return 0;
}

输出显示,第一次调用总是比其余的多花费大约2000个周期

cycles: 5185
cycles: 3049
cycles: 2981
cycles: 2830
cycles: 2851
cycles: 2767
cycles: 2694
cycles: 2570
cycles: 2517
cycles: 2490

我的想法是,在第一个函数调用中,函数代码本身被加载到像L1缓存一样的内存中,然后执行函数代码。到下一次函数调用时,函数代码将已经在缓存中,因此CPU不必花费周期来执行此操作,它可以再次运行函数。这就是为什么第一次调用foo要比其他调用花费更长的时间

此外,请注意,调用另一个代码位于内存中foo旁边的函数也可以将foo带入内存,因为操作系统一次加载几页内存。我已经测试过了,它有时似乎有效,所以对此持怀疑态度。我想编译器会使函数定义的二进制文件的位置不确定。因此,在第一次调用函数代码之前,函数代码可能会在缓存中,但如果没有,则在CPU真正运行代码之前,需要额外的几个周期才能将其放入缓存中。

最新更新