如何将__m128i转换为__m256i,同时将高位设置为零?

问题描述 投票:1回答:1

我希望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有什么解决方法?

c++ visual-c++ simd avx2
1个回答
0
投票

首先,您不需要vpxor ymm0, ymm0, ymm0,因为vmovdqa xmm0, xmm7已将目标ymm / zmm寄存器的高位清零。这与传统的movdqa指令不同,该指令无论如何都不应该在AVX代码中使用。

第二,特定指令的选择是编译器的责任。如果您的编译器生成效率低下的代码,请考虑将错误报告给编译器供应商。例如,gcc识别这种内在模式并生成optimal code

对于MSVC,鉴于不支持x86-64模式下的内联汇编程序,除了使用单独编译的汇编程序源之外,没有可靠的方法来确保特定的指令。您可能会找到一些内部函数的组合,这些内部函数会生成所需的代码,但是这些函数是不可靠的(可能会调用未定义的行为),并且可能会从一个编译器版本更改为另一个编译器版本。

© www.soinside.com 2019 - 2024. All rights reserved.