我正在尝试对数据类型int
,float
和double
运行SIMD指令。
我需要乘法,添加和加载操作。
对于float
和double
,我成功地设法使这些说明有效:
_mm256_add_ps
,_mm256_mul_ps
和_mm256_load_ps
(结束* pd表示双倍)。
(不支持直接FMADD操作)
但是对于整数,我找不到工作指令。在英特尔AVX手册中显示的所有这些都是由GCC 4.7给出了类似的错误,例如"'_ mm256_mul_epu32'未在此范围内声明"。
对于加载整数,我使用_mm256_set_epi32
,这对于GCC来说很好。我不知道为什么没有定义其他指令。我需要更新一些内容吗?
我包括所有<pmmintrin.h>, <immintrin.h> <x86intrin.h>
我的处理器是Intel核心i5 3570k(Ivy Bridge)。
答案 0 :(得分:10)
仅在AVX2之后添加256位整数运算,因此如果您只有AVX1,则必须使用128位__m128i
向量作为整数内在函数。
AVX1确实具有整数加载/存储,并且可以使用FP shuffle或简单加载编译时常量来实现_mm256_set_epi32
之类的内部函数。
https://en.wikipedia.org/wiki/Advanced_Vector_Extensions#Advanced_Vector_Extensions_2
高级矢量扩展2(AVX2),也称为Haswell新指令,[2]是英特尔Haswell微体系结构中引入的AVX指令集的扩展。 AVX2增加了以下内容:
- 将大多数向量整数SSE和AVX指令扩展为256位
- 三操作数通用位操作和乘法
- 三操作数融合乘法 - 累加支持(FMA3)
- 收集支持,启用从非连续内存位置加载矢量元素
- DWORD-和QWORD-granularity any-to-any permutes
- 矢量移位。
FMA3实际上是一个单独的功能; AMD Piledriver / Steamroller拥有它但不支持AVX2。
然而,如果int值范围符合24位,那么您可以使用float
代替。但请注意,如果您需要完全结果或结果的低位,那么您必须将float
转换为double
,因为24x24乘法将产生48位结果,该结果只能存储在double
中。此时,每个向量仍然只有4个元素,并且使用int32
的XMM向量可能会更好。 (但请注意,FMA吞吐量通常优于整数乘法吞吐量。)
AVX1具有128位整数运算的VEX编码,因此您可以在与256位FP内部函数相同的函数中使用它们,而不会导致SSE-AVX转换停顿。 (在C中,您通常不必担心;您的编译器会在需要时使用vzeroupper
。
您可以尝试使用AVX按位指令(如VANDPS和VXORPS)来模拟整数加法,但是对于ymm向量没有按位左移,它将无法工作。
如果您确定未设置FTZ / DAZ,则可以使用小整数作为非正规/次正常float
值,其中尾数外的位均为零。然后FP加法和整数加法是相同的按位运算。 (当输入和结果都不正常时,VADDPS不需要在Intel硬件上使用微代码辅助。)