Spectre 修复对排序性能的影响

Spectre fix impact on sorting performance

famous Whosebug questions 之一是为什么对已排序的数组进行排序如此之快;答案是因为分支预测。

英特尔和微软的幽灵修复程序的应用是否会有效地使这个问题中对受影响的处理器(老一代英特尔处理器、AMD Ryzen 和 ARM)给出的答案无效?

不,Spectre 的关键是强制 indirect 分支的错误预测,因为它们可以跳转到任何地址。找到一个加载你想要的秘密数据的指令序列,然后用秘密作为数组索引进行另一个数据相关的加载是非常重要的。

要攻击常规的采用/不采用条件分支(就像您在排序函数中找到的,或者在排序或未排序数组的循环中的条件分支),您需要找到一个执行分支的 "wrong" 一侧(可能是源代码中 if/else 的错误一侧)的情况在使用寄存器中的 "wrong" 值运行时会做一些有用的事情。这似乎有道理1,但不太可能,因此大多数针对 Spectre 的防御只会担心间接分支。


Spectre 的硬件修复必须比 "turn off branch prediction" 更微妙(即在每个条件分支处停止管道)。 这可能会降低性能在许多代码中的数量级,并且太高以至于不能成为 acceptable 防御本地信息泄漏(这可能导致特权升级)。

即使只关闭间接分支的预测(但不是常规条件分支)对于大多数用户来说可能太昂贵了-space代码,因为每个共享库/DLL 函数调用都会在主流 OSes 上通过正常软件生态系统中的间接分支(Linux,OS X,Windows ).

Linux 内核正在试验 以击败内核 内部间接分支的间接分支预测 。不过,我不确定它是否默认启用,即使在启用 Meltdown 解决方法 (KPTI) 的内核中也是如此。


脚注:

  1. 有时 switch 的错误 case 可能会做一些完全不合适的事情(例如在解释器中),如果 switch 是用嵌套分支而不是单个间接分支编译的分支然后你也许可以攻击它。 (编译器通常为 switch 使用 table 个分支目标,但当情况稀疏时,并不总是可行。例如 case 10 / case 100 / case 1000 / default 需要一个只有 3 个使用值的 990 条目数组。)