当硬件预测不可用时,x86/ARM CPU 为何不停止对间接分支的推测?

问题描述 投票:0回答:1

正如英特尔优化手册中所述:

间接分支和调用的默认预测目标是 跌倒路径。如果并且当 硬件预测可用于该分支。

对于间接 JMP,我们只需执行下一条直线指令。在硬件预测可用之前,默认预测主要会损害性能(可能导致资源冲突并减慢分支恢复速度)。并且它引入了直线推测(SLS)漏洞。

这与间接调用相同,只是解码后的指令可以重复使用。

那么,在这种情况下,CPU 设计者为什么不像 INT3/UD2 那样停止猜测呢?

x86 cpu-architecture branch-prediction
1个回答
0
投票

它有时确实有助于按照英特尔的建议优化跳转表的代码,使目标之一(最好是最常见的)成为失败,通常可能用于

switch
语句。 (间接的就没有那么多了
call

我认为这种行为早在超线程出现之前就被设计到了 P6 中,因此从其他逻辑核心窃取执行资源对于不太可能是正确路径的执行路径来说并不是一件事情。

最旧的就绪优先 uop 调度使得这种推测的执行路径不太可能在跳转之前从代码中窃取周期。我认为飞行中的

div
或负载可以在不等待完成的情况下被取消,所以这不应该是一个大因素;您是否有任何数据支持您对已知良好执行路径中的早期工作的资源冲突的担忧?我猜想,如果错误推测的负载耗尽了等待无用缓存行的 LFB,则可能会延迟有用负载的进度,而该负载的地址直到此后才准备好。它当然会污染缓存和 TLB。

Spectre 是在 2017 年左右才构思出来的;在此之前,CPU 架构师甚至没有考虑来自不影响架构状态的推测执行的任何类型的安全威胁。如果任何英特尔架构师早在 90 年代初设计 P6 时就对此类漏洞有任何概念,那么 Meltdown 就不会出现,大多数 MDS 漏洞也不会出现。


如果 CPU did 停止获取,则需要重新启动它。我想也许执行产生正确地址的间接

jmp
/
call
可能会触发这一点,但它可能需要特殊的机制? (或者也许不是,当我写完本节时,我想可能不是。)

如果

ud2
/
int
达到退休状态,就会陷入陷阱,这是一件非常复杂的事情,总是涉及从新位置重新启动读取,而 ROB(重新排序缓冲区)和调度程序已经为空,因为这些指令总是停止读取。与间接调用或跳转不同,在您提出的设计中,间接调用或跳转仍然会推测分支目标预测是否可用。

因此,我怀疑当前设计的 CPU 内部结构简单是有好处的,CPU 不同部分的特殊情况较少。就目前所需的晶体管数量而言,这可能不是什么大问题,但在第一代 P6 中可能意义重大。

分支恢复机制显然经过高度优化,可以尽可能降低分支未命中延迟。我不知道是否有任何障碍可以连接到该机制以停止获取/解码并需要重新启动它。可能不会;错误推测的

int
ud2
可能会停止 fetch,并且执行分支需要重新启动 fetch。

因此间接

jmp
call
已经需要能够重新启动 fetch,所以这可能不是什么大问题。

© www.soinside.com 2019 - 2024. All rights reserved.