4

我有一个在 Intel 和 AMD x86 机器上运行的应用程序的 MASM 同步代码。

我想使用 Intel TSX 前缀来增强它,特别是 XACQUIRE 和 XRELEASE。

如果我为 Intel 正确修改我的代码,当我尝试在 AMD 机器上运行它时会发生什么?英特尔表示,这些设计是为了向后兼容,大概意味着它们在没有 TSX 的英特尔 CPU 上什么都不做。

我知道 AMD 还没有实现 TSX。但是这些前缀在 AMD CPU 上运行安全吗?这种行为是否记录在 AMD 手册中的某个地方,或者假设这是安全的并且永远是安全的,是在玩火吗?

4

1 回答 1

6

xacquire/xrelease只是 F2/F3 REP 前缀所有不支持该功能的 CPU(包括非 Intel)都会安全地忽略它。这就是英特尔选择该编码作为前缀的原因。它甚至比必须作为单独指令解码的 NOP 更好。

通常(跨供应商),CPU 会忽略他们不理解的 REP 前缀。 因此,新扩展可以使用 REP 作为其编码的一部分,如果它对它们在旧 CPU 上解码为其他东西有用,而不是#UD.

我认为 AMD 为ed 指令或 mov-storesrep上的前缀引入不兼容的含义是不合理的lock——这会破坏已经使用这些前缀的现实世界的二进制文件。例如,我很确定主流 GNU/Linux 发行版中的一些 libpthread 构建已经使用它来启用硬件锁省略,并且不使用动态 CPU 调度来运行基于 CPUID 的不同代码。


使用 REP 作为向后兼容新指令的强制前缀之前已经完成,例如使用rep nop=pauserep bsf= tzcnt。(对编译器很有用,因为tzcnt在某些 CPU 上速度更快,并且如果输入已知为非零,则给出相同的结果。)rep ret作为 AMD 推土机前分支预测器的解决方法,GCC 广泛使用 - `rep ret` 是什么意思? . 那个毫无意义的 REP 在 AMD 的实践中确实有效(默默地忽略)。

(反之则不然。您不能编写依赖于被未来CPU 忽略的无意义 REP 前缀的软件。后来的一些扩展可能会给它一个含义,例如,与rep bsrwhich run as 一样lzcnt并给出不同的结果。这就是为什么英特尔将无意义前缀的影响记录为“未定义”。)


我想使用 Intel TSX 前缀来增强它,特别是 XACQUIRE 和 XRELEASE。

不幸的是,微码更新显然禁用了所有 Intel CPU 上 TSX 的 HLE(硬件锁定消除)部分。(也许可以减轻TAA 侧信道攻击)。这与使jcc32 字节块末尾无法在 uop 缓存中缓存的更新相同,因此很难通过对现有代码进行基准测试来判断无 HLE 部分的性能影响。

https://news.ycombinator.com/item?id=21533791 /由于 Spectre 缓解,硬件锁定消除是否永远消失了?(是的,消失了,但原因可能不是 Spectre 的具体原因。IDK 如果它会回来。)

如果您想在 x86 上使用硬件事务内存,我认为您唯一的选择是 RTM ( xbegin/ xend),即 TSX 的另一半。在最近的微码更新之后,操作系统也可以禁用它;我不确定典型系统的默认设置是什么,这可能会在未来发生变化,因此在将开发时间投入任何事情之前需要检查一下。

AFAIK 没有使用 RTM 的方法,但可以透明地回退到锁定;xbegin / xend 是非法指令,#UD如果 CPUID 功能位不存在,则会出错。

如果您想要透明的向后兼容,那么您应该使用 HLE,所以它(以及一般的 TSX)经历了如此艰难的时期,并且反复被微码更新禁用,这真是太可惜了。(以前在 Haswell 和 Broadwell 中,因为可能存在正确性错误。现在变成了Charlie Brown 的情况。)

于 2020-04-20T10:44:21.023 回答