我希望 VC++ 发出这样的代码:
vpxor ymm0, ymm0, ymm0
vmovdqa xmm0, xmm7
用人类语言来说,我想要一个 32 字节 __m256i
value,其中最低 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模式下不支持内联汇编器,因此除了使用单独编译的汇编器源之外,没有可靠的方法来确保特定的指令。您可能会发现一些内在函数的组合可以生成您想要的代码,但这将是不可靠的(并且可能会调用未定义的行为),并且可能会从一个编译器版本更改为另一个编译器版本。
关于c++ - 如何将 __m128i 转换为 __m256i,同时将高位设置为零?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60074111/