
[英]How do direct number operands in a CPU work?
举一个例子:x86_64 CPU读取一条128位指令。 据我了解,这很明显是x86处理器中发生的事情。 否则,例如不可能将64位数字添加到64位寄存器中(对于数字> 64,操作码将需要几位+ 64位)。 我想知道的是一条指令中的位限制是什么,并且如果该指令大于位(数据总线), ...
[英]How do *move elimination* slots work in Intel CPU?
提示:本站为国内最大中英文翻译问答网站,提供中英文对照查看,鼠标放在中文字句上可显示英文原文。
Andreas Abel 和 Jan Reineke 在他们描述 uiCA 的论文中讨论了移动消除:
4.1.4移动消除。 [...] 然而,这一举动消除并不总是成功的。 [...] 我们开发了微基准测试,使用这些计数器来分析移动消除何时成功。 [...]
以下 model 同意我们的观察。 处理器跟踪被多个架构寄存器使用的物理寄存器。 我们说每个这样的物理寄存器占用一个淘汰槽。 淘汰槽在相应的寄存器被覆盖后再次释放。 * 一个循环中可以消除的移动指令数量取决于可用消除槽的数量,以及前一个循环中成功消除的数量。
我在我不理解的部分添加了重点。
我认为给定的物理寄存器只能由一个架构寄存器从重命名到退休使用。 我把文本的意思理解为其他意思,所以我很难理解移动消除槽是如何工作的(在这一点上,甚至寄存器重命名实际上是如何工作的)。
mov-elimination 的全部意义在于,不是分配新的 PRF 条目(物理寄存器文件)并运行 uop 来读取值并将其写入新条目(如lea rdx, [rcx+0]
会), mov rdx, rcx
可以通过使 RDX 的 RAT 条目(寄存器分配表)指向与 RCX 在该点相同的物理寄存器号来处理。
所以整个想法是在某个时候改变 PRF 条目的规则是单个体系结构寄存器的 state。 这可能会使跟踪何时可以释放 PRF 条目变得更加复杂,或者当两个架构寄存器都引用相同的物理 reg 或其他一些复杂情况时重命名以后的 uops。
“移动消除槽”是一个单独的资源,而不是 PRF 条目。 它们的存在是为了解决英特尔遇到的任何额外跟踪问题。 当您稍后再次覆盖mov
的目标时,将释放移动消除槽,例如mov ecx, edx
/ not ecx
立即释放所需的任何移动消除资源。
没有移动消除,你对它的工作原理是正确的; 一个 PRF 条目仅保存写入一个体系结构寄存器的值,并且是在覆盖之前读取该寄存器的任何微指令的输入依赖项。
除了 PRF 条目也有 FLAGS 条件代码的空间,所以在像add eax, ecx
这样写入 FLAGS 和 integer reg 的指令之后,RFLAGS 和 RCX 都指向同一个物理 reg。 后面的指令,如mov
-immediate、 not
或lea
可以覆盖 gp 寄存器,只留下 CF 和 SPAZO 的 FLAGS 组指向旧的物理寄存器。 诸如cmp
、 stc
或add [mem], eax
之类的指令写入(部分)FLAGS 但不是 integer 寄存器。
但这只是两件事(FLAGS、 CF 和 SF/PF/AF/ZF/OF aka SPAZO的单独重命名部分)可能仍然指的是 phys reg,而不是 GP 整数寄存器。 每个 phys reg 可能有 1 位来跟踪它是否仍然被 GP 整数 reg 引用,退休可以在退休写入 GP 整数寄存器的 uop 时正确释放它们,可能只是检查 RAT 条目的退休 state对于旗帜。 或者也许每个 PRF 条目都有 3 位,一个用于 GP 整数、CF 和 SPAZO,作为退休的一种方式来确定何时可以释放物理寄存器(当它退休覆盖最后一个体系结构引用的 uop 时)它。)
BeeOnRope 建议,不是在每个 PRF 条目中进行完整的引用计数(在mov ecx, eax
/ mov edx, eax
/... 的情况下,计数器最多可以计数 15),移动消除槽实际上是引用计数。
异或归零总是可以被消除,因为物理零寄存器永远不需要被释放,所以它不需要被引用计数。 (integer 和向量的物理零寄存器的存在是从 SnB 系列能够消除归零习惯用法这一事实推断出来的,因为没有 uops。)
相关: x86 的 MOV 真的可以“免费”吗? 为什么我根本无法重现这个? 其中提到了一些Intel的优化手册所说的关于宁愿尽快覆盖寄存器副本的结果,以提高mov-elimination的成功率。 但英特尔至少当时并没有提及涉及到什么CPU资源限制的细节。
Skylake 比 Ivy Bridge 有更多的 mov-elimination slots,因为我的测试表明它没有在测试用例中遇到瓶颈,他们用来说明迅速覆盖 mov 的好处。
非常不幸的是,英特尔搞砸了 Ice Lake / Tiger Lake 并且不得不通过微代码更新禁用其 mov-elimination(对于 GP-integer),因为立即覆盖mov
通常意味着它是关键路径延迟的一部分,与如果您的代码可以在没有移动消除的情况下在 CPU 上运行,那么您想要什么。 它在 Alder Lake 和 Rocket Lake 再次工作。
在许多情况下,您很快就会覆盖副本和原始文件,因此通过几条指令保持目的地不变就可以了。 理想情况下,避免长期不修改副本,除非它会花费更多的 uops 或使 Ice Lake 上的关键路径延迟更糟。 (例如,如果您保存了一个副本并且只读过它。)下一个中断通常会导致所有 regs 无论如何都被保存/恢复,所以这不是一个可以“建立”的问题,即使对于有一些 long-运行具有许多 mov-eliminated 副本的循环。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.