【发布时间】:2017-02-13 06:23:28
【问题描述】:
repz ret 的问题已在此处 [1] 以及其他来源 [2, 3] 非常令人满意地进行了介绍。然而,没有阅读这些资料,我找到了以下问题的答案:
在与
ret或nop; ret的定量比较中,实际惩罚是多少?尤其是在后一种情况下——当大多数函数要么有 100 多个或者被内联时,解码一个额外的指令(以及一个空的指令!)真的相关吗?为什么这个问题在 AMD K8 中从未得到修复,甚至进入了 K10?既然什么时候基于一个保持未记录的行为记录一个丑陋的解决方法,而不是实际解决问题,当原因的每个细节都知道的时候?
【问题讨论】:
-
感谢匿名投票,它确实有助于澄清这个问题。
-
这显然有助于防止分支错误预测,这是一个相当大的惩罚,但实际惩罚会因情况而异。我不确定您为什么将解决方法称为麻烦或丑陋的解决方法,因为解决方法实现起来再简单不过了,也不难理解。另一方面,在硬件中解决问题意味着完全重新设计分支预测器。这不一定是整体改进,除非增加用于实现它的宝贵裸片空间量。
-
@RossRidge 这很丑,因为它没有反映
rep前缀的描述或目的。正如我在另一个问题及其来源中所读到的那样,它只允许字符串指令,而使用ret一个 UB。该定义从未更新以反映(并因此正式证明)已成为普遍做法的内容。 在主要供应商处具有已知行为的 UB 仍然是 UB。 此外,因为它不会以任何方式考虑ecx,尽管人们可能期望它的行为至少在 = 0 时有所不同vs. ≠ 0。不可否认,nop在所有这些方面都会更干净。 -
嗯,不,这里不是在谈论符合某些官方标准。所有与 x86 兼容的 CPU 都会忽略非字符串指令上的 0xF3 (REP) 前缀,因为原始 8086 就是这样做的。任何不这样做的 CPU 都不兼容 x86。这是英特尔在创建 PAUSE 指令(实际上是 REP NOP)以及后来创建 XACQUIRE 和 XRELEASE 前缀(实际上分别是 REP 和 REPNE 前缀)时利用的东西。这些都被记录为向后兼容,因为它们只是提示,而较旧的 CPU 会忽略“提示”。
-
不幸的是,英特尔和 AMD 对澄清这方面的任何事情都没有太大兴趣。 x86 兼容 CPU 必须实现的所有未记录行为都会给任何其他潜在竞争对手造成负担。如果 CPU 没有忽略 RET 指令前面的 REP 前缀,Windows 可能无法启动,因为它在
__security_check_cookie中使用,所以这是一个竞争对手必须正确处理的细节示例。
标签: assembly x86 micro-optimization amd-processor branch-prediction