c - C中的整数SIMD指令AVX

标签 c gcc simd avx

我正在尝试对数据类型运行 SIMD 指令 int , floatdouble . 我需要乘法、加法和加载操作。

对于 floatdouble我成功地使这些说明起作用:

_mm256_add_ps , _mm256_mul_ps_mm256_load_ps (以 *pd 结尾为 double)。 (不支持直接 FMADD 操作)

但是对于整数我找不到有效的指令。英特尔 AVX 手册中显示的所有内容均由 GCC 4.7 给出类似的错误,例如“‘_mm256_mul_epu32’未在此范围内声明”。

为了加载整数,我使用 _mm256_set_epi32这对 GCC 来说很好。我不知道为什么没有定义其他指令。我需要更新什么吗?

我包括所有这些 <pmmintrin.h>, <immintrin.h> <x86intrin.h>

我的处理器是 Intel core i5 3570k (Ivy Bridge)。

最佳答案

自 AVX2 以来才添加 256 位整数运算,因此如果您只有 AVX1,则必须使用 128 位 __m128i vector 来处理整数内在函数。

AVX1 确实有整数加载/存储,并且像 _mm256_set_epi32 这样的内在函数可以用 FP 洗牌或编译时常量的简单加载来实现。

https://en.wikipedia.org/wiki/Advanced_Vector_Extensions#Advanced_Vector_Extensions_2

Advanced Vector Extensions 2 (AVX2), also known as Haswell New Instructions,[2] is an expansion of the AVX instruction set introduced in Intel's Haswell microarchitecture. AVX2 makes the following additions:

  • expansion of most vector integer SSE and AVX instructions to 256 bits
  • three-operand general-purpose bit manipulation and multiply
  • three-operand fused multiply-accumulate support (FMA3)
  • Gather support, enabling vector elements to be loaded from non-contiguous memory locations
  • DWORD- and QWORD-granularity any-to-any permutes
  • vector shifts.

FMA3 实际上是一个单独的功能; AMD Piledriver/Steamroller 有,但 AVX2 没有。

不过,如果 int 值范围适合 24 位,那么您可以改用 float。但是请注意,如果您需要精确结果结果的低位,则必须将float 转换为double ,因为 24x24 乘法将产生 48 位结果,只能精确存储在 double 中。那时每个 vector 仍然只有 4 个元素,使用 int32 的 XMM vector 可能会更好。 (但请注意,FMA 吞吐量通常优于整数乘法吞吐量。)

AVX1 具有 128 位整数运算的 VEX 编码,因此您可以在与 256 位 FP 内在函数相同的函数中使用它们,而不会导致 SSE-AVX 转换停滞。 (在 C 语言中,您通常不必担心这一点;您的编译器会在需要时负责使用 vzeroupper。)

您可以尝试使用 AVX 按位指令(如 VANDPS 和 VXORPS)模拟整数加法,但如果 ymm vector 没有按位左移,它将无法工作。

如果您确定未设置 FTZ/DAZ,则可以使用小整数作为非正规/次正规float 值,其中尾数之外的位均为零.那么FP加法和整数加法是同一个位运算。 (当输入和结果都是非正规的时,VADDPS 不需要 Intel 硬件上的微码辅助。)

关于c - C中的整数SIMD指令AVX,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24399754/

相关文章:

c# - 使用 SIMD 内部函数时这些额外的反汇编指令是什么?

c++ - 良好的可移植 SIMD 库

c - 为什么单独的 getaddrinfo-like() + connect() 没有重构为(理论上的)connect_by_name()?

c - GCC - 添加库

c++ - 计算文本文件中的行数

C - 强制字符串参数在只读内存中

c - 通过SSE2加快矩阵乘法

c - 如何从完整字符串中获取子字符串?

c - 保持数组不在 RAM 中

c - 扫描文件并分配正确的空间来保存文件