使用汇编语言进行128位移位?

Łuk*_*Lew 8 performance x86 assembly 128-bit

在现代英特尔CPU(核心i7,沙桥)上进行128位移位的最有效方法是什么?

类似的代码在我最内层的循环中:

u128 a[N];
void xor() {
  for (int i = 0; i < N; ++i) {
    a[i] = a[i] ^ (a[i] >> 1) ^ (a[i] >> 2);
  }
}
Run Code Online (Sandbox Code Playgroud)

数据a[N]几乎是随机的.

GJ.*_*GJ. 12

使用指令Shift Double.

所以SHLDSHRD说明,因为SSE不是为此目的.有一种clasic方法,这里有32位和64位CPU模式下128位左移16位的测试用例.

通过这种方式,您可以执行无限大小的移位,最高可达32/64位.Yoo可以移位立即数位或cl寄存器中的数字.第一个指令操作符也可以处理内存中的变量.

在32位x86 CPU模式下,128位左移16位:

    mov     eax, $04030201;
    mov     ebx, $08070605;
    mov     ecx, $0C0B0A09;
    mov     edx, $100F0E0D;

    shld    edx, ecx, 16
    shld    ecx, ebx, 16
    shld    ebx, eax, 16
    shl     eax, 16
Run Code Online (Sandbox Code Playgroud)

在64位x86 CPU模式下,128位左移16位:

    mov    rax, $0807060504030201;
    mov    rdx, $100F0D0E0B0C0A09;

    shld   rdx, rax, 16
    shl    rax, 16
Run Code Online (Sandbox Code Playgroud)

  • 我用过这个.它工作且速度相当快,但你应该提到32位代码允许最多移位31和64位代码最多63.如果你想换一个可变数量,这不能保证小于64,这不能用. (2认同)