我相信,在创建 CPU 时,如果选择了错误的分支,分支预测会导致速度显着下降。那么,为什么 CPU 设计者选择一个分支,而不是简单地执行两个分支,然后在确定选择了哪个分支后就切断其中一个分支呢?
我意识到这只能在少量指令内深入 2 或 3 个分支,否则并行阶段的数量会变得非常大,因此在某些时候您仍然需要一些分支预测,因为您肯定会运行更大的分支,但是这样的几个阶段难道没有意义吗?在我看来,这会显着加快速度,并且值得增加一点复杂性。
即使只有一个分支深,几乎一半的时间都会被错误的分支吃掉,对吗?
或者也许已经这样做了?当你开始组装时,分支机构通常只会在两个选择之间进行选择,对吗?
你担心机器会呈指数级增长是对的,但你低估了它的力量。
一个常见的经验法则是,您的动态代码中平均会有约 20% 的分支。这意味着每 5 条指令中有一个分支。如今,大多数 CPU 都有一个深度乱序核心,可以提前获取并执行数百条指令 - 以英特尔的 Haswell 为例,它有一个192 http://www.realworldtech.com/haswell-cpu/3/条目 ROB,这意味着您最多可以容纳 4 层分支(此时您将拥有 16 个“前沿”和 31 个“块”,每个块包括一个分叉分支 - 假设每个块将有 5 条指令,您几乎已经填满了ROB,另一个级别会超过它)。到那时,您只能达到约 20 条指令的有效深度,从而使任何指令级并行性变得毫无用处。
如果您想在 3 个级别的分支上发散,则意味着您将有 8 个并行上下文,每个上下文只有 24 个条目可用于提前运行。即使这样,只有当您忽略回滚 7/8 工作的开销、复制所有状态保存硬件(如寄存器,您有数十个)的需要以及像您一样将其他资源分成 8 个部分的需要时与 ROB 一起做。另外,这还不包括内存管理,内存管理必须管理复杂的版本控制、转发、一致性等。
忘记功耗吧,即使您可以支持那种浪费的并行性,在您可以在每条路径上推进更多指令之前,将资源分散到如此薄的程度实际上会让您感到窒息。
现在,让我们检查一下拆分单个分支的更合理选项 - 这开始看起来像超线程 - 您可以在 2 个上下文中拆分/共享核心资源。当然,此功能具有一些性能优势,但这只是因为两个上下文都是非推测性的。事实上,我认为,根据工作负载组合(来自 AnandTech 的评论),通常的估计是依次运行 2 个上下文的效率约为 10-30%here http://www.anandtech.com/show/2594/8) - 如果您确实打算一个接一个地运行这两个任务,那么这很好,但当您要丢弃其中一个任务的结果时则不然。即使您忽略此处的模式切换开销,您获得 30% 的收益也只会损失 50% - 这毫无意义。
另一方面,您可以选择预测分支(当今的现代预测器平均成功率可以达到 95% 以上),并支付错误预测的惩罚,这已经被乱序引擎部分隐藏了(某些分支之前的指令可以在分支被清除后执行,大多数 OOO 机器都支持这一点)。这使得任何深度乱序引擎可以自由地向前漫游,推测其全部潜在深度,并且在大多数情况下都是正确的。这里某些工作被刷新的几率确实呈几何级数下降(第一个分支后为 95%,第二个分支后约为 90%,等等),但刷新惩罚也会减少。它仍然比 1/n 的全局效率(对于 n 级分叉)要好得多。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)