让我们假设一个简单的if
像这样:
if (something)
// do_something
else
// do_else
假设这个if-else
语句在不同的线程中并行执行,并且每个线程产生不同的结果,但在其自身生命中保持不变。例如,在线程1中,条件总是被评估为false,在线程2中为true;在线程3中也总是如此,等等。
分支预测是否考虑每个线程的执行上下文来进行统计?因为如果不这样(我不认为,但很难通过测试来检查),CPU会看到条件遵循随机模式而根本无法预测。
答案 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个分支,希望这些分支可以减少工作量。