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处理器控制器的异构多核处理器的体系结构。新的体系结构避免了由于分支未命中预测而导致的管道刷新,提高了多核处理器的整体效率。参考: