使用AVX异或两个zmm(512位)寄存器

时间:2019-07-29 13:34:55

标签: c++ gcc inline-assembly avx512

我想用zmm1来位xor xor zmm0。 我在互联网上阅读并尝试过:

asm volatile(
            "vmovdqa64 (%0),%%zmm0;\n"
            "vmovdqa64 (%1),%%zmm1;\n"
            "vpxorq %%zmm1, %%zmm0;\n"
            "vmovdqa64 %%zmm0,(%0);\n"

            :: "r"(p_dst), "r" (p_src)
             : );

但是编译器给出“错误:'vpxorq'的操作数不匹配”。

我在做什么错了?

2 个答案:

答案 0 :(得分:2)

为此,内联汇编是毫无意义的( https://gcc.gnu.org/wiki/DontUseInlineAsm ),即使您通过添加第三个操作数来修复语法错误,您的代码也不安全且效率低下。

使用内部_mm512_xor_epi64( __m512i a, __m512i b); ,如Intel's asm manual entry for pxor中所述。如果要查看完成情况,请查看编译器生成的asm。

不安全,因为您没有"memory"垃圾桶来告诉编译器您读/写内存,并且没有在zmm0zmm1上声明垃圾桶

低效的原因有很多,包括强制使用寻址模式和不使用内存源操作数。而不是让编译器选择要使用的寄存器。


只需修复asm语法,使其编译便会从出现明显的编译时错误变为细微而危险的运行时错误,只有在启用优化后才能看到。

有关内联汇编的更多信息,请参见https://stackoverflow.com/tags/inline-assembly/info。但是同样,对于大多数SIMD来说,基本上没有理由使用它,因为您可以使编译器使asm的效率与您可以手工完成的效率相同,并且效率更高。 >

答案 1 :(得分:0)

大多数AVX512指令使用3个以上的操作数,即您需要添加其他操作数-dst寄存器(它可以与其他操作数之一相同)。

AVX2版本也是如此,请参见https://www.felixcloutier.com/x86/pxor

  

VPXOR ymm1,ymm2,ymm3 / m256

     

VPXORD zmm1 {k1} {z},zmm2,zmm3 / m512 / m32bcst

请注意,以上内容是intel语法,大约会转换为* mm1 = * mm2 ^ ** mm3,在您的情况下,我想您想使用"vpxorq %%zmm1, %%zmm0, %%zmm0;\n"

请注意,对于真正特殊的情况,使用内联汇编通常是一种不好的做法。通过使用所有主要编译器支持的内在函数,SIMD编程会更好(更快,更容易)。您可以在这里浏览它们:https://software.intel.com/sites/landingpage/IntrinsicsGuide/