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

标签 c++ visual-c++ simd avx2

我希望 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/

相关文章:

c++ - 可能的内存泄漏?

c++ - 内置 CArray 的 CMap

c++ - StrRetToBuf 函数的链接器错误

assembly - MOVDQA 和 MOVNTDQA 以及 WB/WC 标记区域的 VMOVDQA 和 VMOVNTDQ 之间有什么区别?

c++ - avx浮点按位逻辑运算的原因是什么?

c++ - 为什么我们需要默认构造函数来在 C++ 中通过引用传递对象?

c++ - Qtwebengine进程在应用程序关闭后没有关闭

c++ - wait_until 在主线程中的工作方式与主线程中的工作方式是否不同?由 小码哥发布于

c++ - 自定义对象的 vector

c++ - 与 ARM Neon vtbx 的字节序混淆