以下是我正在分析的代码:
#include <iostream>
#include <fstream>
#define N 10000
using namespace std;
int main()
{
ofstream fout;
fout.open("log.txt");
int A[N], B[N], C[N];
for(int i=0; i<N; i++)
{
A[i] = B[i] = i;
}
int sum = 0;
for(int j=0; j<N; j++)
{
C[j] = A[j]+B[j];
//fout<<C[j]<<endl;
sum += C[j];
sum %= 103;
}
cout<<sum<<endl;
return 0;
}
以下是分析命令:
perf stat -e instructions:u -e instructions:k -e cache-misses -e page-faults -e branch-misses ./test
输出是:
Performance counter stats for './test':
15,60,186 instructions:u
8,35,753 instructions:k
24,345 cache-misses
123 page-faults
13,051 branch-misses
0.001327182 seconds time elapsed
但是,当我取消注释该单个注释行时,我得到以下输出:
Performance counter stats for './test':
75,72,868 instructions:u
12,29,31,625 instructions:k
2,18,333 cache-misses
121 page-faults
73,662 branch-misses
0.525844017 seconds time elapsed
我无法理解是什么导致缓存未命中的大幅增加以及分支未命中的适度高增长。任何见解都将不胜感激!
答案 0 :(得分:4)
没有&#34; fout<<C[j]<<endl;
&#34;您的程序主要在用户空间中运行(我更确切地说,您的程序的重要部分是完全在用户空间中运行)。通过取消注释该行(在循环内),您将引入许多额外的系统调用(这通过探查器报告的instructions:k
数量的大幅增加来显示)。系统调用很昂贵,因为它们涉及上下文切换,根据硬件架构和操作系统,它可能会使CPU缓存的显着部分无效。
请注意,这里的主要罪魁祸首是endl
(强制刷新缓冲区,从而触发系统调用)。将其替换为'\n'
,对性能的影响要小得多。