使用x86 / x64程序集进行旋转或移位

时间:2015-12-06 12:42:01

标签: assembly x86-64

我有功能,我在汇编时写作,我想确定什么能给我最好的吞吐量。

我在RAX中有64位值,我需要获得最高字节并对其执行一些操作,我想知道最好的方法是什么。

shr  rax, 56    ; This will get me the most significant byte in al.

然而,这比......更有效。

rol  rax, 8
and  rax, r12   ; I already have the value 255 in r12

我之所以要问的是,在某些架构中,换档速度是您所做换档次数的函数。如果我记得,在680x0芯片上它是6 + 2n,其中n是移位计数。我不认为这在x86架构上是正确的,但我不确定......所以人们的一些启示会受到赞赏。 (我理解延迟)

还是有一种简单的方法可以将RAX的0-31位与32-64位交换而不是旋转或移位?像680x0上的交换一样。

1 个答案:

答案 0 :(得分:2)

根据http://agner.org/optimize/的指令表,具有立即计数的rol是单uop / m-op指令,在Intel(Pentium M到Haswell)和AMD(K8)上有1个周期延迟到Steamroller)。吞吐量范围从每时钟一个到每个时钟三个。

使用可变计数(rol r, cl)进行旋转在英特尔上速度较慢,在AMD上速度相同。

显然,如果您提出这类问题,请阅读Agner Fog的指南,因为高性能比单独使用单指令更多。

如果您在多个数据项上执行此操作,则可以在16B(带SSE的xmm寄存器)或32B(带有AVX的ymm寄存器)块上同时使用向量shuffle。 pshufd xmm, xmm, imm将允许您为每个输出dword选择任何输入dword。 (所以你可以广播和填充,以及简单的随机播放。)