分支预测和多线程

时间:2016-09-18 12:24:19

标签: multithreading branch-prediction

让我们假设一个简单的if像这样:

if (something)
   // do_something
else
   // do_else

假设这个if-else语句在不同的线程中并行执行,并且每个线程产生不同的结果,但在其自身生命中保持不变。例如,在线程1中,条件总是被评估为false,在线程2中为true;在线程3中也总是如此,等等。

分支预测是否考虑每个线程的执行上下文来进行统计?因为如果不这样(我不认为,但很难通过测试来检查),CPU会看到条件遵循随机模式而根本无法预测。

1 个答案:

答案 0 :(得分:3)

如果我们忽略SMT(f.ex。超线程),大多数架构都会为每个硬件线程提供一个分支预测器。 它与单个核心的获取单元紧密耦合。少数(AMD?)在L1 / L2 I-cache中存储了一些分支预测信息,但主要针对下一次获取。

因此,如果你没有在SMT上运行代码,那么你就是在天堂,并且每次都会以一些指令为代价得到100%的预测。

如果你在SMT上运行你的代码,你会发现你的生活很糟糕,有50%以上的误预测。

现在您可以轻松解决问题,只需使用更多代码,提前检查条件并使用do_something或do_else调用代码分支。

如果你有一个循环来调用你的分支,你可以做以下的事情:

if(something)   do_something_loop(); 其他   do_else_loop();

void do_something_loop(){   for(auto x:myVec)     做一点事; }

这样做的缺点是你需要维护两个几乎相等的代码分支。

或者你可以在函数调用branch_me()中使用你的分支,你可以创建一个模板函数,并且由于死代码消除的魔力,你不应该在循环中得到任何分支。

C ++概念代码。

template<bool b_something>
void brancher() {
  // do things
  if (b_something)
    // do_something
  else
    // do_else
  }
  // do more things
}

void branch_user() {
  if (something) {
    for (auto x : myVec)
      brancher<true>();
  } else {
    for (auto x : myVec)
      brancher<false>();
  }
}

现在你只需要维护外部函数的2个分支,希望这些分支可以减少工作量。