我想将16个无符号的32位整数的两个512位__m512i vector 相乘,并从乘法的64位结果中仅取高32位。尽管英特尔内在函数指南说_mm512_mulhi_epu32存在,但无法在我的计算机上编译。
答案here声称_mm512_srli_epi64(_mm512_mul_epu32(a,b),32)可以工作,但是不起作用-问题似乎是_mm512_mul_epu32仅考虑位0 ... 31、64 ... 95等,而忽略了奇数位置的值。
如何最快地从32位 vector 乘法的结果中提取高32位?

最佳答案

vpmuludq aka _mm512_mul_epu32采用偶数源32位元素(0、2、4等)1。这样,它就可以在每个64位块中高效执行,将输入的低32位输入到FP尾数乘法器。这是一个扩展的aka全倍运算,而不是高半倍乘,因此,它当然必须忽略某些输入(因为没有SIMD数学指令具有两个 vector 目标)。
因此,您需要使用它两次才能获得所需的所有上半结果:一次在偶数位置使用奇数元素,一次在偶数位置使用奇数元素(向右移动两个输入 vector )。然后,您需要从这些64位元素中插入高半部分。
诀窍就是有效地做到这一点:AVX-512 vpermt2d从2个源 vector 中选择32位元素可以一次完成工作。因此,这很棒,尤其是在一个循环中,该循环使编译器可以提升随机控制 vector 常量的负载。其他选项包括_mm512_mask_shuffle_epi32(带有合并掩码的 vpshufd ),将上半部分向下复制到1个 vector 中,并合并到结果的另一个 vector 中,并在k寄存器中提供了合并控制。 (vpmuludq结果之一在您想要的位置有一半,因为输入是右移的)。 vmovshdup (_mm512_mask_movehdup_ps)在少1字节的机器代码中执行相同的随机播放,不需要立即执行。内在函数很不方便,因为您需要使用__m512i__m512转换为_mm512_castsi512_ps,但是应该具有相同的性能。
甚至存储两次,并为第二个存储区加上 mask ,但这可能很糟糕,因为其中一个存储区必须未对齐(从而导致64字节存储区的高速缓存行交叉)。尽管如此,它确实避免了任何其他ALU运维。
更加“显而易见”的选项(就像您对AVX2所做的那样)将是vpsrld(_mm512_srli_epi64(v,32))其中之一,然后是vpblendd。但这要花费2个单独的ALU运算符,并且在当前CPU上使用512位 vector 意味着只有2个 vector ALU执行端口可以处理它们。另外,vpblendd没有AVX-512版本;只有混合将控制操作数带入k寄存器中。 (使用shift / AND和OR合并会更糟,并且仍然需要 vector 常量)

__m512i mulhi_epu32_512(__m512i a, __m512i b)
{
    __m512i evens = _mm512_mul_epu32(a,b);
    __m512i odds = _mm512_mul_epu32(_mm512_srli_epi64(a,32), _mm512_srli_epi64(b,32));
    return _mm512_mask_shuffle_epi32(odds, 0x5555, evens, _MM_SHUFFLE(3,3,1,1));

    // _mm512_mask_movehdup_ps may be slightly more efficient, saving 1 byte of code size
}
对于独立功能,clang会优化该合并 mask 的混洗,使其具有内存中的 vector 常量作为vpermi2d,而不是mov eax, 0x5555 / kmovw k1, eax或其他内容。包含安装程序时,操作会减少,但可能会缓存未命中。 GCC按照书面形式进行编译。 https://godbolt.org/z/v4M7PK显示了两者。对于循环主体(悬挂设置),任一种方式都是单个uop,但是合并屏蔽的vpshufd仅具有1个延迟周期,而穿越车道的vpermi2d / vpermt2d仅具有3个延迟周期。 (https://uops.info/https://agner.org/optimize/)

脚注1:您链接的Q&A不能完全描述问题和/或解决方案,或者实际上仅需要2个数字(在 vector 的底部?),而不是2个数字的 vector 。

关于c++ - 将32位整数的 vector 相乘,仅占用高32位,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/64852344/

10-11 00:55
查看更多