vpbroadcastw指令在AVX2中方便地引入(?)在32字节ymm寄存器中向所有位置广播低16位字.
因为我是逆反派,所以我想将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字节的洗牌控制。
发布于 2019-08-15 05:26:13
AVX512BW vpermw可以在SKX和更高版本上完成这一任务。在SKX上有2个uop,但在后来的Intel上下降到1uop。
使用AVX2,您可以通过两个直接的洗牌来分两个步骤广播,而不需要控制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))我认为至少需要两个非洗牌指令(如vpsrld / vpblendw)才能设置一个vpermd (带有控制向量)来广播高dword。但这并没有帮助,因为vpblendw是P5--甚至在SKL/SKX上也是如此。
另外,如果洗牌吞吐量是瓶颈,则存储/重新加载也是一种选择,例如vextracti128的上半部分,然后从该高字开始广播负载。(但比dword更窄的广播负载仍然需要一次洗牌。)
https://stackoverflow.com/questions/57505111
复制相似问题