我希望VC++发出如下代码:
vpxor ymm0, ymm0, ymm0
vmovdqa xmm0, xmm7
用人类语言,我想要一个32字节的
__m256i
值,其中最低16个字节来自另一个变量,而最高16个字节为零。相当于_mm256_castsi128_si256
内部函数,只需要高128位为零即可,而不是未定义。这是我尝试过的:
_mm256_setr_m128i( low, _mm_setzero_si128() )
_mm256_insertf128_si256( _mm256_setzero_si256(), low, 0 )
上面的两行都编译为
vinsertf128
,相对较慢,延迟3-4个周期,比vmovdqa
慢得多。 VC++ 2017有任何解决方法吗? 最佳答案
首先,您不需要vpxor ymm0, ymm0, ymm0
,因为vmovdqa xmm0, xmm7
已经将目标ymm
/ zmm
寄存器的高位清零了。这与传统的movdqa
指令不同,该指令无论如何都不应该在AVX代码中使用。
其次,特定指令的选择是编译器的责任。如果您的编译器生成效率低下的代码,请考虑将错误报告给编译器供应商。例如,gcc识别这种内在模式并生成optimal code。
对于MSVC,由于不支持x86-64模式下的内联汇编程序,因此没有可靠的方法来确保特定的指令,除非使用单独编译的汇编程序源。您可能会发现一些内部函数的组合,这些内部函数会生成所需的代码,但是这些函数是不可靠的(可能会调用未定义的行为),并且可能会从一个编译器版本更改为另一个编译器版本。