如何计算分支的错误预测?

时间:2018-12-08 15:09:20

标签: branch-prediction

我有一个任务来计算分支预测错误的惩罚(以滴答为单位),因此我编写了以下代码:

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等辅助程序的情况下做到这一点?

1 个答案:

答案 0 :(得分:0)

这取决于您使用的处理器,通常可以使用cpuid获取有关处理器的大量信息,并且通常可以通过smbios或其他内存区域访问cpuid不提供的信息。

在没有处理器支持功能和手册的情况下,以一般级别在代码中执行此操作不会在很大程度上确定所需的信息,但根据您的查找内容和方式,此估计可能有用您的代码已编译,例如您在编译等过程中使用的标志。

通常,所谓的“镜面执行”或“推测执行”通常不会被程序观察到,因为它们的逻辑在管道中的转换被确定为未使用,然后被丢弃。

根据您在程序中使用特定指令的方式,您也许可以使用这种陈旧的缓存信息,无论是好是坏,但其中的逻辑会根据所使用的CPU的不同而有很大差异。

有关将此类技术用于特权执行的有趣示例,另请参阅Spectre和RowHammer。

有关具有与cpuid以及rdrand,rdseed和其他一些用法有关的代码的链接,请参见下面的注释。 (rdtsc)

尚不清楚您在寻找什么,但是肯定会帮助您入门并提供一些有用的示例。

另请参阅Branch mispredictions