典型的现代CPU的分支预测缓冲区有多大?

时间:2012-09-10 15:59:26

标签: c++ performance cpu branch-prediction

我正在处理的应用程序有大量的if语句,其特征是在任何一次执行中,只有一个分支在90%的时间内执行。

现在,我可以通过执行以下操作来测试分支预测对特定CPU的单个if语句的影响: -

#include <iostream>
#include <stdlib.h>

using namespace std;

int main() {
  int a;
  cin>>a;
  srand(a);
  int b;

  long count=0;

  for (int i=0; i<10000; i++) {
    for (int j=0; j<65535; j++) {
      b = rand() % 30 + 1;
      if (b > 15) // This can be changed to get statistics for different %-ages
        count += (b+10);
    }
  }

  cout << count <<"\n";
}

我的问题是,是否有一种方法可以在给定CPU的实际大型应用程序中使用多个if语句测试分支预测的可伸缩性和影响?

基本上,我希望能够弄清楚在不同的CPU上花费多少分支错误预测以及它们对应用程序的影响。

1 个答案:

答案 0 :(得分:4)

您需要考虑分支的复杂性,编译器可能会使用体系结构特定的操作代码(如CMOV(比较和移动))删除分支。

您的简单示例代码

if (b > 15)
    count += (b+10);

这是编译成机器语言的代码

;; assembly x86 FASM/NASM syntax

;; WITH branching
MOV ebx, [b] ;; b
MOV ecx, [count] ;; count
CMP ebx, 15 ;; if condition to set flags
JLE .skip ;; { branch/jump over the if body when less than or equal
LEA eax, [ecx + ebx + 10] ;; count + b+10
MOV [count], eax ;; store count
.skip: ;; } label after the if block

;; WITHOUT branching
MOV ebx, [b] ;; b
MOV ecx, [count] ;; count
LEA eax, [ecx + ebx + 10] ;; pre-calc avoiding the need to branch
CMP ebx, 15 ;; if condition to set flags
CMOVLE eax, ecx ;; make eax equal to ecx (current count) when less than or equal
            ;; avoiding the branch/jump
MOV [count], eax ;; store count

因此,除非您知道优化编译器如何优化代码,否则分析分支预测有点困难。如果您正在检查机器代码输出并知道您有很多J [condition]语句,那么使用注释中提到的代码分析工具就足够了。尝试在不使用适当的架构调试寄存器的情况下推出自己的分支预测测试将导致我在上面演示的情况。