我有一项任务要计算分支预测失误的惩罚(以刻度为单位(,所以我写了以下代码:
int main (int argc, char ** argv) {
unsigned long long start, end;
FILE *f;
f = fopen("output", "w");
long long int k = 0;
unsigned long long min;
int n = atoi(argv[1]);// n1 = atoi(argv[2]);
for (int i = 1; i <= n + 40; i++) {
min = 9999999999999;
for(int r = 0; r < 1000; r++) {
start = rdtsc();
for (long long int j = 0; j < 100000; j++) {
if (j % i == 0) {
k++;
}
}
end = rdtsc();
if (min > end - start) min = end - start;
}
fprintf (f, "%d %lld n", i, min);
}
fclose (f);
return 0;
}
(rdtsc是一个以节拍为单位测量时间的函数(
这个代码的想法是,它周期性地(周期等于i(进入分支(如果(j%i==0((,所以在某个时候它开始进行错误预测。代码的其他部分大多是多重测量,我需要得到更精确的结果。
测试表明,分支预测失误在i=47左右开始发生,但我不知道如何计算预测失误的确切数量来计算蜱虫的确切数量。有人能向我解释一下,如何在不使用像Vtune这样的辅助程序的情况下做到这一点吗?
这取决于您使用的处理器,通常情况下,cpuid可以用于获取有关处理器的大量信息,而cpuid没有提供的信息通常可以通过smbios或其他内存区域访问。
在没有处理器支持功能和手册的情况下,在一般级别的代码中这样做不会告诉你想要的那么多确定性,但可能是有用的估计,这取决于你在寻找什么以及你如何编译代码,例如你在编译过程中使用的标志等。
通常,被称为镜面反射或推测执行的内容通常不会被程序观察到,因为通过管道转换的逻辑被确定为不被使用,然后被丢弃。
根据您在程序中使用特定指令的方式,您可能会更好或更糟地使用这种过时的缓存信息,但其中的逻辑会因使用的CPU而异。
另请参阅Spectre和RowHammer,了解使用此类技术进行特权执行的有趣示例。
请参阅下面的注释,以获取包含与cpuid以及rdrand、rdseed和其他一些代码的使用相关的代码的链接。(rdtsc(
目前还不完全清楚你在寻找什么,但肯定会让你开始并提供一些有用的例子。
另请参阅分支预测失误