像往常一样,检查拆卸。然后,事实证明,无论如何,我使用的编译器依赖于该数据是一个编译时间常量,并重新排列它以便可以轻松加载。如果这是实际上在你的真实代码的情况下,这是没有问题的(但为什么不使用数组开头?)。但是,如果我怀疑这是,这仅仅是一个例子,实际的阵列是可变的,这是一场灾难,只要看看它:
movzx eax, BYTE PTR [rsp+95]
xor ebx, ebx
mov BYTE PTR [rsp], al
movzx eax, BYTE PTR [rsp+93]
vmovd xmm7, DWORD PTR [rsp]
vpinsrb xmm7, xmm7, BYTE PTR [rsp+94], 1
mov BYTE PTR [rsp], al
movzx eax, BYTE PTR [rsp+91]
vmovd xmm3, DWORD PTR [rsp]
vpinsrb xmm3, xmm3, BYTE PTR [rsp+92], 1
mov BYTE PTR [rsp], al
movzx eax, BYTE PTR [rsp+89]
vmovd xmm1, DWORD PTR [rsp]
vpinsrb xmm1, xmm1, BYTE PTR [rsp+90], 1
mov BYTE PTR [rsp], al
movzx eax, BYTE PTR [rsp+87]
vmovd xmm6, DWORD PTR [rsp]
vpunpcklwd xmm3, xmm7, xmm3
vpinsrb xmm6, xmm6, BYTE PTR [rsp+88], 1
mov BYTE PTR [rsp], al
movzx eax, BYTE PTR [rsp+85]
vmovd xmm5, DWORD PTR [rsp]
vpinsrb xmm5, xmm5, BYTE PTR [rsp+86], 1
mov BYTE PTR [rsp], al
movzx eax, BYTE PTR [rsp+83]
vmovd xmm2, DWORD PTR [rsp]
vpunpcklwd xmm1, xmm1, xmm6
vpinsrb xmm2, xmm2, BYTE PTR [rsp+84], 1
mov BYTE PTR [rsp], al
movzx eax, BYTE PTR [rsp+81]
vmovd xmm0, DWORD PTR [rsp]
vpunpckldq xmm1, xmm3, xmm1
vpinsrb xmm0, xmm0, BYTE PTR [rsp+82], 1
mov BYTE PTR [rsp], al
movzx eax, BYTE PTR [rsp+79]
vmovd xmm4, DWORD PTR [rsp]
vpunpcklwd xmm2, xmm5, xmm2
vpinsrb xmm4, xmm4, BYTE PTR [rsp+80], 1
mov BYTE PTR [rsp], al
movzx eax, BYTE PTR [rsp+77]
vmovd xmm8, DWORD PTR [rsp]
vpinsrb xmm8, xmm8, BYTE PTR [rsp+78], 1
mov BYTE PTR [rsp], al
movzx eax, BYTE PTR [rsp+75]
vpunpcklwd xmm0, xmm0, xmm4
vmovd xmm4, DWORD PTR [rsp]
vpinsrb xmm4, xmm4, BYTE PTR [rsp+76], 1
mov BYTE PTR [rsp], al
movzx eax, BYTE PTR [rsp+73]
vpunpckldq xmm0, xmm2, xmm0
vmovd xmm2, DWORD PTR [rsp]
vpinsrb xmm2, xmm2, BYTE PTR [rsp+74], 1
mov BYTE PTR [rsp], al
movzx eax, BYTE PTR [rsp+71]
vmovd xmm7, DWORD PTR [rsp]
vpunpcklqdq xmm1, xmm1, xmm0
vpunpcklwd xmm4, xmm8, xmm4
vpinsrb xmm7, xmm7, BYTE PTR [rsp+72], 1
mov BYTE PTR [rsp], al
movzx eax, BYTE PTR [rsp+69]
vmovd xmm6, DWORD PTR [rsp]
vpinsrb xmm6, xmm6, BYTE PTR [rsp+70], 1
mov BYTE PTR [rsp], al
movzx eax, BYTE PTR [rsp+67]
vmovd xmm0, DWORD PTR [rsp]
vpunpcklwd xmm2, xmm2, xmm7
vpinsrb xmm0, xmm0, BYTE PTR [rsp+68], 1
mov BYTE PTR [rsp], al
movzx eax, BYTE PTR [rsp+65]
vmovd xmm5, DWORD PTR [rsp]
vpunpckldq xmm2, xmm4, xmm2
vpinsrb xmm5, xmm5, BYTE PTR [rsp+66], 1
mov BYTE PTR [rsp], al
vmovd xmm3, DWORD PTR [rsp]
vpunpcklwd xmm0, xmm6, xmm0
vpinsrb xmm3, xmm3, BYTE PTR [rsp+64], 1
vpunpcklwd xmm3, xmm5, xmm3
vpunpckldq xmm0, xmm0, xmm3
vpunpcklqdq xmm0, xmm2, xmm0
vinserti128 ymm0, ymm1, xmm0, 0x1
vmovdqa YMMWORD PTR [rsp+32], ymm0
哇。好吧,不太好。事实上,如果同样的事情没有内在因素,但并非全部都失败了,那就更糟了。这将是更好地加载数据作为小端的uint,然后交换他们周围有_mm256_shuffle_epi8
,有点像这样(但检查洗牌面膜,我没有测试)
__m256i ymm9 = _mm256_shuffle_epi8(_mm256_load_si256((__m256i*)block), _mm256_set_epi8(
0, 1, 2, 3,
4, 5, 6, 7,
8, 9, 10, 11,
12, 13, 14, 15,
0, 1, 2, 3,
4, 5, 6, 7,
8, 9, 10, 11,
12, 13, 14, 15));
ymm9 = _mm256_permute2x128_si256(ymm9, ymm9, 1);
_mm256_store_si256((__m256i*)m, ymm9);
一般情况下,要非常小心“内置”系列内部函数,它们可以编译成非常糟糕的指令序列。
pre meture优化,只是memcpy – user3528438
为什么不使用简单的位移? –
你确定你想要big-endian语义吗? – chqrlie