vpbroadcastw
AVX2 中引入的指令方便 (?) 将低 16 位 WORD 广播到 32 字节中的所有位置 ymm
登记。
因为我是逆势投资者,所以我想将 AVX2 寄存器的高位字(位 255:240)广播给所有元素。
我能想到的最好的办法是一个车道交叉洗牌,然后是 pshufb
逐字节洗牌,如下所示:
inline __m256i bcast_mse(__m256i v) {
__m256i temp = _mm256_permute2x128_si256(v, v, 0x11);
__m256i ctrl = _mm256_set_epi8( // clang-format off
15, 14, 15, 14, 15, 14, 15, 14,
15, 14, 15, 14, 15, 14, 15, 14,
15, 14, 15, 14, 15, 14, 15, 14,
15, 14, 15, 14, 15, 14, 15, 14
); // clang-format on
return _mm256_shuffle_epi8(temp, ctrl);
}
有更好的吗?显然我更喜欢单条指令,但假设这不会发生,也许需要这个 32 字节随机控制。
最佳答案
AVX512BW vpermw
可以在 SKX 及更高版本上执行此操作。在 SKX 上为 2 uop,但在后来的 Intel 上降低到 1 uop。
使用 AVX2,您可以分 2 步进行广播,两次立即随机播放,无需控制 vec:
vpshufhw ymm
_mm256_shufflehi_epi16(v, _MM_SHUFFLE(3,3,3,3))
vpermq
广播即时。_mm256_permute4x64_epi64
或 _mm256_permutex_epi64(v2, _MM_SHUFFLE(3,3,3,3))
我认为至少需要 2 条非随机指令(如
vpsrld
/vpblendw
)来设置 vpermd
(带有控制向量)广播高双字。但这无济于事,因为 vpblendw
即使在 SKL/SKX 上也是 p5-only。如果 shuffle 吞吐量是瓶颈,则存储/重新加载也是一种选择,例如
vextracti128
的高半,然后从高字广播负载。 (但比双字更窄的广播负载仍然需要 shuffle uop)。
关于x86 - AVX2中广播高字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57505111/