_mm256_loadu2_m128i 内在函数在 g++ 下不可用?

Posted

技术标签:

【中文标题】_mm256_loadu2_m128i 内在函数在 g++ 下不可用?【英文标题】:_mm256_loadu2_m128i intrinsic not available under g++? 【发布时间】:2013-12-15 06:26:03 【问题描述】:

我正在尝试使用 AVX2 内在 _mm256_loadu2_m128i,但似乎 g++ 4.8.2 没有它。

有什么方法可以得到吗?

【问题讨论】:

这不是我熟悉的内在特性。它映射到什么指令? @CoryNelson 它没有。英特尔内在指南是这样说的:“注意:这个内在创造了两个或更多指令的序列,并且可能比本机指令执行得更差。考虑这个内在的性能影响。” 我看到的唯一参考使用VMOV/VINSERT 非常简单地实现了它。 我现在没有对 hand 的内在函数引用,但我相信有一个或多或少等效的 _mm256_set_xxx 内在函数。 是的。这是真的。你可以在这里看到它:godbolt.org/g/EUnXSe 将编译器切换到 gcc 并看到它失败了...... 【参考方案1】:

我在 GCC 和 Clang 中遇到了同样的问题。但是它在 ICC 中编译。您可以在http://gcc.godbolt.org/ 使用 GCC、Clang 和 ICC 进行测试

注意,这是一个 AVX 内在而不是 AVX2。大多数 256 位整数加载和存储内在函数只需要 AVX。 AVX2 提供了一些收集和屏蔽负载,但其他一切都只需要 AVX。

由于 Haswell 可以一次加载两个 128 位值,因此您可以使用 _mm256_inserti128_si256 实现与 _mm256_loadu2_m128i 相同的效果。像这样的

#include <immintrin.h>

int main() 
    int low[4];
    int high[4];
    _mm256_inserti128_si256(_mm256_castsi128_si256(
        _mm_loadu_si128((__m128i*)low)),
        _mm_loadu_si128((__m128i*)high),1);

【讨论】:

clang-3.3 将在针对 avx 而不是 avx2 时从正常的loadu 操作生成加载 + 插入序列。 例如:gcc.godbolt.org/…*x%2C%20__m256d%20y)%20%7B%5Cn%20%20return%20_mm256_add_pd(_mm256_loadu_pd(x)%2Cy)%3B%5Cn%7D% 5Cn%22%2C%22compiler%22%3A%22%2Fopt%2Fclang-3.3%2Fbin%2Fclang%2B%2B%22%2C%22options%22%3A%22-O2%20-mavx%22%7D% 5D%7D 稍微简洁一点的版本:_mm256_set_m128i(_mm_loadu_si128(hi), _mm_loadu_si128(lo))。编译成同样的东西。【参考方案2】:

猜猜不存在名为_mm256_loadu_m128i 的内在函数。我能用_mm256_load找到的只有_mm256_load_pd_mm256_load_ps_mm256_load_si256_mm256_loadu_pd_mm256_loadu_ps_mm256_loadu_si256。 这些都带有 AVX,gcc 标头是immintrin.h

【讨论】:

_mm256_loadu2_m128i,而不是_mm256_loadu_m128i。另请参阅英特尔内部指南中的 _mm256_loadu_m128i

以上是关于_mm256_loadu2_m128i 内在函数在 g++ 下不可用?的主要内容,如果未能解决你的问题,请参考以下文章

试图理解 _mm256_permute2x128_si256 的英特尔内在指南解释

用内在函数初始化 __m128i 常量的最快方法?

256 位块的 CRC 计算

在 GCC 10.3.0 中找不到 _mm256_rem_epu64 内在函数

尝试特别使用内在函数时出现分段错误_mm256_storeu_pd()

使用 __builtin_popcount 或其他内在函数来处理 _mm256_movemask_pd 比较位图的结果?