使用CL寄存器的移位会导致部分寄存器停顿吗?

时间:2012-10-27 20:00:05

标签: performance assembly x86

变量移位能否在ecx上产生部分寄存器停顿(或寄存器重组μops)?如果是这样,哪个微体系结构?

我在Core2(65nm)上测试了这个,它似乎只读cl

_shiftbench:
    push rbx
    mov edx, -10000000
    mov ecx, 5
  _shiftloop:
    mov bl, 5   ; replace by cl to see possible recombining
    shl eax, cl
    add edx, 1
    jnz _shiftloop
    pop rbx
    ret

mov bl, 5替换mov cl, 5没有任何区别,如果进行了注册重组,则会有所不同,可以通过shl eax, cl替换add eax, ecx来证明我的测试add的版本在写入cl而不是bl时经历了2.8倍的减速。


测试结果:

  • Merom:没有观察到失速
  • Penryn:没有观察到失速
  • Nehalem:没有观察到失速

更新:新的shrx - Haswell 中的一组班次显示停止。 shift-count参数不是写成8位寄存器,因此可能是预期的,但文本表示实际上并没有说明这些微架构细节。

1 个答案:

答案 0 :(得分:4)

正如目前的措辞(“可以使用CL寄存器移位......”)问题的标题包含其自己的答案:使用现代处理器,CL上永远不会有部分寄存器停止,因为CL永远不能从较小的东西重新组合。

是的,处理器知道您正在移位的数量有效地包含在CL中,确切地说,CL的5或6个最低有效位。它可能在ECX上停滞的一种方式是,它认为指令依赖性的粒度没有低于完整寄存器。然而,这种担心已经过时了:最新的英特尔处理器将整个ECX寄存器视为依赖是Pentium 4.请参阅Agner Fog的unofficial optimization manual,第121页。但话说再说一次,P4不会被称为部分寄存器停止,该程序只能成为虚假依赖的受害者(例如,如果CH在移位之前是修饰符)。