【问题标题】:How to count branch mispredictions?如何计算分支错误预测?
【发布时间】:2019-05-10 01:31:30
【问题描述】:

我有一个任务来计算分支误预测惩罚(以滴答计),所以我写了这段代码:

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)进入分支(if (j % i == 0)),所以在某些时候它开始做错误预测。代码的其他部分大多是多次测量,我需要得到更精确的结果。

测试表明分支错误预测开始发生在 i = 47 左右,但我不知道如何计算错误预测的确切数量来计算确切的滴答数。谁能向我解释一下,如何在不使用 Vtune 之类的辅助程序的情况下做到这一点?

【问题讨论】:

  • 别忘了对有帮助的答案进行投票,并接受解决您问题的答案!

标签: branch-prediction


【解决方案1】:

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

在没有处理器支持功能和手册的情况下,在一般级别的代码中执行此操作不会告诉您尽可能多的确定性,但根据您的查找内容和您拥有的方式,作为估计可能有用你的代码编译例如您在编译期间使用的标志等。

一般来说,所谓的镜面或推测执行,通常不会被程序观察到,因为它们通过管道转换的逻辑被确定为不使用。

根据您在程序中使用特定指令的方式,您可能会更好或更差地使用此类陈旧的缓存信息,但其中的逻辑会因使用的 CPU 的不同而有很大差异。

另请参阅 Spectre 和 RowHammer,了解使用此类技术进行特权执行的有趣示例。

请参阅下面的 cmets 以获取与 cpuid 以及 rdrand、rdseed 和其他一些使用相关的代码的链接。 (rdtsc)

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

另见Branch mispredictions

【讨论】:

  • 问题是我需要通过测试而不是使用软件来获取这些数据
  • 您将需要使用软件来执行这些指令,以获取您需要检查的信息以及解释这些值;这些变化会根据 CPU 的型号而有所不同...另请参阅:github.com/juliusfriedman/net7mma/blob/… 一旦您有了获取所需信息的路径,您通常会在调用您的分析之前/之后插入一个带有测量逻辑的函数获得结果...有很多因素,包括缓存大小等....
猜你喜欢
  • 2013-10-09
  • 2018-09-29
  • 2020-01-13
  • 2016-02-05
  • 2015-03-31
  • 2015-09-25
  • 2017-10-04
  • 2014-04-25
  • 2014-03-03
相关资源
最近更新 更多