分支预测和除零

Ann*_*inn 28 c++ error-handling optimization cpu-architecture branch-prediction

我写的代码看起来像以下......

if(denominator == 0){
    return false;
}
int result = value / denominator;
Run Code Online (Sandbox Code Playgroud)

...当我考虑CPU中的分支行为时.

/sf/answers/785953171/ 这个答案说CPU将尝试正确猜测分支将走向哪个方向,并且如果发现分支错误地猜测分支,那么只停下该分支停止.

但是如果CPU预测上面的分支不正确,它将在以下指令中除以零.虽然这不会发生,我想知道为什么?CPU是否实际执行除零并在执行任何操作之前等待分支是否正确,还是可以告诉它在这些情况下不应该继续?这是怎么回事?

MSa*_*ers 26

当基于预测推测性地执行分支时,CPU可以随心所欲地做任何事情.但它需要以对用户透明的方式这样做.因此它可能会出现"除以零"故障,但如果分支预测错误则应该不可见.通过相同的逻辑,它可以将写入分段写入内存,但它实际上可能不会提交它们.

作为一名CPU设计师,我不打算预测过去这样的错误.这可能不值得.这个错误可能意味着一个糟糕的预测,这将很快解决.

这种自由是一件好事.考虑一个简单的std::accumulate循环.分支预测器将正确预测大量跳转(for (auto current = begin, current != end; ++current)通常跳回到循环的开始),并且存在大量可能发生故障的内存读取(sum += *current).但是,在前一个分支被解析之前拒绝读取内存值的CPU会慢得多.然而,在循环结束时错误预测的跳转可能会导致无害的内存故障,因为预测的分支会尝试读取缓冲区.这需要在没有明显故障的情况下解决.


Ser*_*sta 6

不完全是.系统不允许在错误的分支中执行指令,即使它做了错误的猜测,或者更确切地说,如果它确实不可见.基本是:

  • 在机器代码的某处有一个测试.
  • 处理器使用其中一条可能路径上的指令加载管道,并可能在内部执行它们- 根据MSalters,某些处理器甚至可以执行两条路径(*)
  • 如果它做得很好,很好,下面的指令已预先加载到处理器缓存中或已经执行,并且所有内容都尽可能快
  • 如果它做出了错误的猜测,它只需清理所有内容并重新启动正确的分支.

对于与参考岗位的类比,如果开关位置不正确,火车必须立即停在路口,不能在错误的路径上到达下一站,或者如果在此之前无法停止,则不允许乘客进出火车

(*)Itanium处理器可以并行处理多个路径.英特尔的逻辑是,他们可以构建宽处理器(并行执行大量处理),但他们正在努力解决有效指令速率问题.通过推测性地执行两个分支,他们使用了大量的硬件(我认为它们可以在几个层次上运行,运行2 ^ N个分支)但它确实有助于明显的单核速度,因为它实际上总是在一个硬件中预测正确的分支单位 - 积分应该转到MSalters以获得该精度