2016-09-18 70 views
1

让我们假设一个简单的if这样的:分支预测和多线程

if (something) 
    // do_something 
else 
    // do_else 

假设这if-else声明是在不同的线程并行执行,每个线程产生不同的结果,而是通过自己的生命不断。例如,在线程1中,条件总是被评估为false,在线程2中为true;在线程3中也总是如此,等等。

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

+1

定义线程。 CPU显然不知道操作系统线程。但是现在大多数CPU都知道硬件线程。 –

+1

分支预测是以纳秒分辨率运行的处理器实现细节。线程执行以毫秒分辨率运行。这6个数量级的差异使问题无关紧要。 –

回答

1

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

所以,如果你没有在SMT你在天上运行你的代码,并会得到100%的预测在几个指令的成本每一次。

如果您在SMT运行你的代码,你会经常发现你的生活就是地狱,有50 +%错误预测。

现在您可以轻松解决你的问题,你只需要使用更多的代码,请检查您的病情较早,并调用你的代码的分公司与do_something或它do_else。

如果你有一个循环调用你的函数,你有你的分支,你可以这样做:

如果(东西) do_something_loop(); else do_else_loop();

void do_something_loop(){ for(auto x:myVec) do_something; }

这有您需要维护的代码2个几乎相等分支机构的缺点。

或者你可以在一个函数调用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个分支。