【问题标题】:How large is the branch prediction buffer for a typical modern CPU?典型的现代 CPU 的分支预测缓冲区有多大?
【发布时间】:2012-09-03 12:48:19
【问题描述】:

我正在处理的应用程序有大量的 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 上的成本以及它们对应用程序的影响。

【问题讨论】:

  • 不知道 amd 的产品线,但英特尔处理器有一系列调试寄存器,可以保存诸如分支预测之类的统计信息。如果您可以进入它们,那么获得“总分支”v.s. 将是一件简单的事情。 “失败/成功的预测总数”计数。
  • 您是否尝试过 Vtune 或 PAPI 等分析器?
  • 题主为什么会询问分支预测缓冲区的大小?您的问题主体是关于完全不同的东西:如何获取有关您在代码中产生的分支错误预测惩罚的信息。决定要问的一个问题,然后更新问题标题和正文以反映那个问题:)
  • 所有现代 CPU 有一个分支预测缓冲区。问题是他们使用它的目的(或者更确切地说,他们如何使用它)各不相同,并且周围的分支预测逻辑也各不相同。因此,仅查看该缓冲区的大小几乎不会告诉您任何信息。分支预测器使用许多不同的启发式方法来提高其成功率。
  • 我认为最接近回答问题的方法是阅读“英特尔、AMD 和威盛 CPU 的微架构:汇编程序员和编译器制造商的优化指南”,该指南可在 @ 987654321@。为了摆脱那些讨厌的 if 链,我建议你考虑实现某种 JIT 编译器。

标签: c++ performance cpu branch-prediction


【解决方案1】:

您需要考虑分支的复杂性,编译器可能会使用特定于架构的操作代码(例如 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] 语句,那么使用 cmets 中提到的代码分析工具就足够了。尝试在不使用适当的架构调试寄存器的情况下进行自己的分支预测测试将导致我在上面演示的情况。

【讨论】:

    猜你喜欢
    • 2013-05-07
    • 2015-09-17
    • 2015-09-25
    • 2013-09-26
    • 2012-01-04
    • 2011-04-11
    • 2019-07-24
    • 2022-11-11
    • 2012-07-11
    相关资源
    最近更新 更多