我想对 zmm0 和 zmm1 进行位运算。 我在互联网上阅读并尝试:
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’的操作数数量不匹配”。
我做错了什么?
最佳答案
为此,内联 asm 毫无意义 ( https://gcc.gnu.org/wiki/DontUseInlineAsm ),即使您通过添加第三个操作数修复了语法错误,您的代码也不安全且效率低下。
使用内部 _mm512_xor_epi64( __m512i a, __m512i b);
如 Intel's asm manual entry for pxor 中所述.如果您想了解它是如何完成的,请查看编译器生成的 asm。
不安全,因为您没有 "memory"
clobber 告诉编译器您读/写内存,并且您没有在 zmm0
上声明 clobber或 zmm1
.
而且效率低下的原因有很多,包括强制寻址模式和不使用内存源操作数。并且不让编译器选择要使用的寄存器。
只要修复 asm 语法,使其编译就会从一个明显的编译时错误变成一个微妙而危险的运行时错误,这种错误可能只有在启用优化的情况下才能看到。
参见 https://stackoverflow.com/tags/inline-assembly/info有关内联汇编的更多信息。但同样,对于大多数 SIMD 使用它基本上是零理由,因为您可以让编译器生成 asm,它与您手动执行的操作一样高效,并且比这更高效。 p>
关于c++ - 使用 AVX 异或两个 zmm(512 位)寄存器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57255044/