Multithreading 分支预测和多线程

Multithreading 分支预测和多线程,multithreading,branch-prediction,Multithreading,Branch Prediction,让我们假设一个简单的if如下: if (something) // do_something else // do_else 假设这个if-else语句在不同的线程中并行执行,每个线程产生不同的结果,但在其生命周期中保持不变。例如,在线程1中,条件总是被评估为false,在线程2中,条件总是被评估为true;在线程3中,也总是正确的,以此类推 分支预测是否考虑每个线程的执行上下文来进行统计?因为如果它没有(我不这么认为,但很难通过测试来检查),CPU将看到这种情况遵循随机模式,根本

让我们假设一个简单的
if
如下:

if (something)
   // do_something
else
   // do_else
假设这个
if-else
语句在不同的线程中并行执行,每个线程产生不同的结果,但在其生命周期中保持不变。例如,在线程1中,条件总是被评估为false,在线程2中,条件总是被评估为true;在线程3中,也总是正确的,以此类推

分支预测是否考虑每个线程的执行上下文来进行统计?因为如果它没有(我不这么认为,但很难通过测试来检查),CPU将看到这种情况遵循随机模式,根本不会进行预测。

如果我们忽略SMT(f.ex.hyper threading),大多数体系结构每个硬件线程都有一个分支预测器。 它与单个核心的提取单元紧密耦合。少数(AMD?)将一些分支预测信息存储在一级/二级I-cache中,但主要用于下一次获取

因此,如果你不在SMT上运行你的代码,你就在天堂里,每次都会得到100%的预测结果,而代价是几条指令

如果你在SMT上运行你的代码,你会发现你的生活是地狱,有50%以上的预测失误

现在你可以很容易地解决你的问题了,你只需要使用更多的代码,更早地检查你的情况,并用dou-something或dou-else调用代码的一个分支

如果有一个循环在分支所在的位置调用函数,则可以执行以下操作:

如果(某物) 做点什么; 其他的 do_else_loop()

void do_something_loop(){ 用于(自动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>();
  }
}
模板
空枝(){
//做事
如果(b_某物)
//做点什么
其他的
//还有别的吗
}
//多做事
}
无效分支_用户(){
如果(某物){
用于(自动x:myVec)
brancher();
}否则{
用于(自动x:myVec)
brancher();
}
}

现在您只需维护外部函数的两个分支,希望这会减少工作量。

Define thread。CPU显然不知道操作系统线程。但现在大多数CPU都知道硬件线程。分支预测是一种处理器实现细节,以纳秒分辨率运行。线程执行以毫秒分辨率运行。这6个数量级的差异使问题变得无关紧要。基于多核异构的分支预测的研究与设计摘要:针对单核频率难以提高处理器性能的问题,针对分支指令处理过程中超标量流水线停顿的问题,介绍了采用B-Cache结构和C-core处理器控制器的异构多核处理器的体系结构。新的体系结构避免了由于分支未命中预测而导致的管道刷新,提高了多核处理器的整体效率。参考: