AVX指令使用
Posted walker-lin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AVX指令使用相关的知识,希望对你有一定的参考价值。
一、逻辑运算
相加
__m256d _mm256_add_pd (__m256d a, __m256d b)
__m256 _mm256_add_ps (__m256 a, __m256 b)
相减
__m256d _mm256_sub_pd (__m256d a, __m256d b)
__m256 _mm256_sub_ps (__m256 a, __m256 b)
乘法
__m256d _mm256_mul_pd (__m256d a, __m256d b)
__m256 _mm256_mul_ps (__m256 a, __m256 b)
除法
__m256d _mm256_div_pd (__m256d a, __m256d b)
__m256 _mm256_div_ps (__m256 a, __m256 b)
按位AND
__m256d _mm256_and_pd (__m256d a, __m256d b)
__m256 _mm256_and_ps (__m256 a, __m256 b)
按位OR
__m256d _mm256_or_pd (__m256d a, __m256d b)
__m256 _mm256_or_ps (__m256 a, __m256 b)
按位XOR
__m256d _mm256_xor_pd (__m256d a, __m256d b)
__m256 _mm256_xor_ps (__m256 a, __m256 b)
按位取a的NOT再与b进行AND
__m256d _mm256_andnot_pd (__m256d a, __m256d b)
__m256 _mm256_andnot_ps (__m256 a, __m256 b)
取最大值最小值
__m256d _mm256_max_pd (__m256d a, __m256d b)
__m256 _mm256_max_ps (__m256 a, __m256 b)
__m256d _mm256_min_pd (__m256d a, __m256d b)
__m256 _mm256_min_ps (__m256 a, __m256 b)
交替加减
__m256d _mm256_addsub_pd (__m256d a, __m256d b)
FOR j := 0 to 3
i := j*64
IF (j % 1 == 0)
dst[i+63:i] := a[i+63:i] - b[i+63:i]
ELSE
dst[i+63:i] := a[i+63:i] + b[i+63:i]
FI
ENDFOR
dst[MAX:256] := 0
__m256 _mm256_addsub_ps (__m256 a, __m256 b)
计算a中打包的单精度(32位)浮点元素的近似倒数,并将结果存储在dst中。 该近似的最大相对误差小于1.5 * 2 ^ -12。
__m256 _mm256_rcp_ps (__m256 a)
计算a中打包的单精度(32位)浮点元素的近似倒数平方根,并将结果存储在dst中。 该近似的最大相对误差小于1.5 * 2 ^ -12。
__m256 _mm256_rsqrt_ps (__m256 a)
计算a中打包的双精度(64位)浮点元素的平方根,并将结果存储在dst中。
__m256d _mm256_sqrt_pd (__m256d a)
__m256 _mm256_sqrt_ps (__m256 a)
水平相加相减:
在a和b中水平相加相邻的双精度(64位)浮点元素对,并将结果打包为dst。
__m256d _mm256_hadd_pd (__m256d a, __m256d b)
dst[63:0] := a[127:64] + a[63:0]
dst[127:64] := b[127:64] + b[63:0]
dst[191:128] := a[255:192] + a[191:128]
dst[255:192] := b[255:192] + b[191:128]
dst[MAX:256] := 0
__m256 _mm256_hadd_ps (__m256 a, __m256 b)
dst[31:0] := a[63:32] + a[31:0]
dst[63:32] := a[127:96] + a[95:64]
dst[95:64] := b[63:32] + b[31:0]
dst[127:96] := b[127:96] + b[95:64]
dst[159:128] := a[191:160] + a[159:128]
dst[191:160] := a[255:224] + a[223:192]
dst[223:192] := b[191:160] + b[159:128]
dst[255:224] := b[255:224] + b[223:192]
dst[MAX:256] := 0
在a和b中水平减去相邻的双精度(64位)浮点元素对,并将结果打包为dst。
__m256d _mm256_hsub_pd (__m256d a, __m256d b)
__m256 _mm256_hsub_ps (__m256 a, __m256 b)
二、舍入运算
舍入运算round
__m256d _mm256_ceil_pd (__m256d a)
__m256 _mm256_ceil_ps (__m256 a)
下取整
__m256d _mm256_floor_pd (__m256d a)
__m256 _mm256_floor_ps (__m256 a)
使用舍入参数舍入打包的双精度(64位)浮点元素,并将结果存储为dst中的打包双精度浮点元素。
__m256d _mm256_round_pd (__m256d a, int rounding)
__m256 _mm256_round_ps (__m256 a, int rounding)
三、比较运算
__m128d _mm_cmp_pd (__m128d a, __m128d b, const int imm8)
__m256d _mm256_cmp_pd (__m256d a, __m256d b, const int imm8)
__m128 _mm_cmp_ps (__m128 a, __m128 b, const int imm8)
__m256 _mm256_cmp_ps (__m256 a, __m256 b, const int imm8)
__m128d _mm_cmp_sd (__m128d a, __m128d b, const int imm8)
__m128 _mm_cmp_ss (__m128 a, __m128 b, const int imm8)
四、组合
根据掩码混合两个 __m256d或 __m256
__m256d _mm256_blend_pd (__m256d a, __m256d b, const int imm8)
FOR j := 0 to 3
i := j*64
IF imm8[j]
dst[i+63:i] := b[i+63:i]
ELSE
dst[i+63:i] := a[i+63:i]
FI
ENDFOR
dst[MAX:256] := 0
__m256 _mm256_blend_ps (__m256 a, __m256 b, const int imm8)
__m256d _mm256_blendv_pd (__m256d a, __m256d b, __m256d mask)
FOR j := 0 to 3
i := j*64
IF mask[i+63]
dst[i+63:i] := b[i+63:i]
ELSE
dst[i+63:i] := a[i+63:i]
FI
ENDFOR
dst[MAX:256] := 0
__m256 _mm256_blendv_ps (__m256 a, __m256 b, __m256 mask)
使用imm8控制拖拽128-bit通道内双精度(64位)浮点元素,并将结果存储在dst中。
__m256d _mm256_shuffle_pd (__m256d a, __m256d b, const int imm8)
dst[63:0] := (imm8[0] == 0) ? a[63:0] : a[127:64]
dst[127:64] := (imm8[1] == 0) ? b[63:0] : b[127:64]
dst[191:128] := (imm8[2] == 0) ? a[191:128] : a[255:192]
dst[255:192] := (imm8[3] == 0) ? b[191:128] : b[255:192]
dst[MAX:256] := 0
__m256 _mm256_shuffle_ps (__m256 a, __m256 b, const int imm8)
五、置换
置换permute :使用imm8中的控件来混合双精度(64位)浮点元素,并将结果存储在dst中。
__m128d _mm_permute_pd (__m128d a, int imm8)
IF (imm8[0] == 0) dst[63:0] := a[63:0];
FI IF (imm8[0] == 1) dst[63:0] := a[127:64];
FI IF (imm8[1] == 0) dst[127:64] := a[63:0];
FI IF (imm8[1] == 1) dst[127:64] := a[127:64];
FI dst[MAX:128] := 0
__m256d _mm256_permute_pd (__m256d a, int imm8)
IF (imm8[0] == 0) dst[63:0] := a[63:0];
FI IF (imm8[0] == 1) dst[63:0] := a[127:64]; F
I IF (imm8[1] == 0) dst[127:64] := a[63:0];
FI IF (imm8[1] == 1) dst[127:64] := a[127:64];
FI IF (imm8[2] == 0) dst[191:128] := a[191:128];
FI IF (imm8[2] == 1) dst[191:128] := a[255:192];
FI IF (imm8[3] == 0) dst[255:192] := a[191:128];
FI IF (imm8[3] == 1) dst[255:192] := a[255:192];
FI dst[MAX:256] := 0
__m128 _mm_permute_ps (__m128 a, int imm8)
__m256 _mm256_permute_ps (__m256 a, int imm8)
__m256d _mm256_permute2f128_pd (__m256d a, __m256d b, int imm8)
__m256 _mm256_permute2f128_ps (__m256 a, __m256 b, int imm8)
__m256i _mm256_permute2f128_si256 (__m256i a, __m256i b, int imm8)
__m128d _mm_permutevar_pd (__m128d a, __m128i b)
__m256d _mm256_permutevar_pd (__m256d a, __m256i b)
__m128 _mm_permutevar_ps (__m128 a, __m128i b)
__m256 _mm256_permutevar_ps (__m256 a, __m256i b)
六、广播
广播到低128位
__m256d _mm256_broadcast_pd (__m128d const * mem_addr)
__m256 _mm256_broadcast_ps (__m128 const * mem_addr)
广播到低64位
__m256d _mm256_broadcast_sd (double const * mem_addr)
广播到低32位
__m128 _mm_broadcast_ss (float const * mem_addr)
__m256 _mm256_broadcast_ss (float const * mem_addr)
七、cast与convert
1 cast。此内在函数仅用于编译,不生成任何指令,因此它具有零延迟。
__m256 _mm256_castpd_ps (__m256d a) 将__m256d类型的向量cast为__m256类型。
__m256i _mm256_castpd_si256 (__m256d a)
__m256d _mm256_castpd128_pd256 (__m128d a) 高128位未定义
__m128d _mm256_castpd256_pd128 (__m256d a)
__m256d _mm256_castps_pd (__m256 a)
__m256i _mm256_castps_si256 (__m256 a)
__m256 _mm256_castps128_ps256 (__m128 a)
__m128 _mm256_castps256_ps128 (__m256 a)
__m256i _mm256_castsi128_si256 (__m128i a)
__m256d _mm256_castsi256_pd (__m256i a)
__m256 _mm256_castsi256_ps (__m256i a)
__m128i _mm256_castsi256_si128 (__m256i a)
将__m128d类型的向量转换为类型__m256d; 结果的高128位归零。 此内在函数仅用于编译,不生成任何指令,因此它具有零延迟。
__m256d _mm256_zextpd128_pd256 (__m128d a)
将__m128类型的向量转换为类型__m256; 结果的高128位归零。 此内在函数仅用于编译,不生成任何指令,因此它具有零延迟。
__m256 _mm256_zextps128_ps256 (__m128 a)
将__m128i类型的向量转换为类型__m256i; 结果的高128位归零。 此内在函数仅用于编译,不生成任何指令,因此它具有零延迟。
__m256i _mm256_zextsi128_si256 (__m128i a)
2 convert
__m256d _mm256_cvtepi32_pd (__m128i a)
__m256 _mm256_cvtepi32_ps (__m256i a)
__m128i _mm256_cvtpd_epi32 (__m256d a)
__m128 _mm256_cvtpd_ps (__m256d a)
__m256i _mm256_cvtps_epi32 (__m256 a)
__m256d _mm256_cvtps_pd (__m128 a)
float _mm256_cvtss_f32 (__m256 a)
__m128i _mm256_cvttpd_epi32 (__m256d a)
__m256i _mm256_cvttps_epi32 (__m256 a)
八、提取
提取extract :从a中选择带有索引的32位整数,并将结果存储在dst中。
__int32 _mm256_extract_epi32 (__m256i a, const int index)
__int64 _mm256_extract_epi64 (__m256i a, const int index)
__m128d _mm256_extractf128_pd (__m256d a, const int imm8)
__m128 _mm256_extractf128_ps (__m256 a, const int imm8)
__m128i _mm256_extractf128_si256 (__m256i a, const int imm8)
九、装载数据
将未对齐内存中的256位整数数据加载到dst中。 当数据穿过高速缓存行边界时,此内在函数可能比_mm256_loadu_si256表现更好。
__m256i _mm256_lddqu_si256 (__m256i const * mem_addr)
从内存加载256位(由4个打包的双精度(64位)浮点元素组成)到dst。 mem_addr必须在32字节边界上对齐,否则可能会生成一般保护异常。
__m256d _mm256_load_pd (double const * mem_addr)
从内存加载256位(由8个打包的单精度(32位)浮点元素组成)到dst。 mem_addr必须在32字节边界上对齐,否则可能会生成一般保护异常。
__m256 _mm256_load_ps (float const * mem_addr)
从内存加载256位整数数据到dst。 mem_addr必须在32字节边界上对齐,否则可能会生成一般保护异常。
__m256i _mm256_load_si256 (__m256i const * mem_addr)
从内存加载256位(由4个打包的双精度(64位)浮点元素组成)到dst。 mem_addr不需要在任何特定边界上对齐。
__m256d _mm256_loadu_pd (double const * mem_addr)
__m256 _mm256_loadu_ps (float const * mem_addr)
__m256i _mm256_loadu_si256 (__m256i const * mem_addr)
__m256 _mm256_loadu2_m128 (float const* hiaddr, float const* loaddr)
__m256d _mm256_loadu2_m128d (double const* hiaddr, double const* loaddr)
__m256i _mm256_loadu2_m128i (__m128i const* hiaddr, __m128i const* loaddr)
使用掩码将打包的双精度(64位)浮点元素从存储器加载到dst(当未设置相应元素的高位时,元素被清零)。
__m128d _mm_maskload_pd (double const * mem_addr, __m128i mask)
__m256d _mm256_maskload_pd (double const * mem_addr, __m256i mask)
__m128 _mm_maskload_ps (float const * mem_addr, __m128i mask)
__m256 _mm256_maskload_ps (float const * mem_addr, __m256i mask)
十、卸载数据
使用掩码将打包的双精度(64位)浮点元素存储到内存中。
void _mm_maskstore_pd (double * mem_addr, __m128i mask, __m128d a)
void _mm256_maskstore_pd (double * mem_addr, __m256i mask, __m256d a)
void _mm_maskstore_ps (float * mem_addr, __m128i mask, __m128 a)
void _mm256_maskstore_ps (float * mem_addr, __m256i mask, __m256 a)
将256位(由4个压缩的双精度(64位)浮点元素组成)存储到存储器中。 mem_addr必须在32字节边界上对齐,否则可能会生成一般保护异常。
void _mm256_store_pd (double * mem_addr, __m256d a)
void _mm256_store_ps (float * mem_addr, __m256 a)
void _mm256_store_si256 (__m256i * mem_addr, __m256i a)
void _mm256_storeu_pd (double * mem_addr, __m256d a)
void _mm256_storeu_ps (float * mem_addr, __m256 a)
void _mm256_storeu_si256 (__m256i * mem_addr, __m256i a)
将高和低128位的一半(每个由4个打包的单精度(32位)浮点元素组成)存储到两个不同的128位位置的存储器中。 hiaddr和loaddr不需要在任何特定边界上对齐。
void _mm256_storeu2_m128 (float* hiaddr, float* loaddr, __m256 a)
void _mm256_storeu2_m128d (double* hiaddr, double* loaddr, __m256d a)
void _mm256_storeu2_m128i (__m128i* hiaddr, __m128i* loaddr, __m256i a)
使用非时间内存提示将256位(由4个打包的双精度(64位)浮点元素组成)存储到内存中。 mem_addr必须在32字节边界上对齐,否则可能会生成一般保护异常。
void _mm256_stream_pd (double * mem_addr, __m256d a) (与_mm256_store_pd的区别?)
void _mm256_stream_ps (float * mem_addr, __m256 a)
void _mm256_stream_si256 (__m256i * mem_addr, __m256i a)
十一、对应位置插入(替换)运算
__m256i _mm256_insert_epi16 (__m256i a, __int16 i, const int index)
dst[255:0] := a[255:0] copy
sel := index*16
dst[sel+15:sel] := i[15:0]
__m256i _mm256_insert_epi32 (__m256i a, __int32 i, const int index)
__m256i _mm256_insert_epi64 (__m256i a, __int64 i, const int index)
__m256i _mm256_insert_epi8 (__m256i a, __int8 i, const int index)
__m256d _mm256_insertf128_pd (__m256d a, __m128d b, int imm8)
__m256 _mm256_insertf128_ps (__m256 a, __m128 b, int imm8)
__m256i _mm256_insertf128_si256 (__m256i a, __m128i b, int imm8)
十二、移动数据
从a复制偶数索引(索引从0开始)的双精度(64位)浮点元素,并将结果存储在dst中。
__m256d _mm256_movedup_pd (__m256d a)
dst[63:0] := a[63:0]
dst[127:64] := a[63:0]
dst[191:128] := a[191:128]
dst[255:192] := a[191:128]
dst[MAX:256] := 0
__m256 _mm256_moveldup_ps (__m256 a)
__m256 _mm256_movehdup_ps (__m256 a) 复制奇数索引
根据a中相应的压缩双精度(64位)浮点元素的最高有效位设置掩码dst的每个位。
int _mm256_movemask_pd (__m256d a) 四位有效
int _mm256_movemask_ps (__m256 a) 八位有效
十三、设置:使用提供的值在dst中设置打包的16位整数。
__m256i _mm256_set_epi16 (short e15, short e14, short e13, short e12, short e11, short e10, short e9, short e8, short e7, short e6, short e5, short e4, short e3, short e2, short e1, short e0)
__m256i _mm256_set_epi32 (int e7, int e6, int e5, int e4, int e3, int e2, int e1, int e0)
__m256i _mm256_set_epi64x (__int64 e3, __int64 e2, __int64 e1, __int64 e0)
__m256i _mm256_set_epi8 (char e31, char e30, char e29, char e28, char e27, char e26, char e25, char e24, char e23, char e22, char e21, char e20, char e19, char e18, char e17, char e16, char e15, char e14, char e13, char e12, char e11, char e10, char e9, char e8, char e7, char e6, char e5, char e4, char e3, char e2, char e1, char e0)
__m256 _mm256_set_m128 (__m128 hi, __m128 lo)
__m256d _mm256_set_m128d (__m128d hi, __m128d lo)
__m256i _mm256_set_m128i (__m128i hi, __m128i lo)
__m256d _mm256_set_pd (double e3, double e2, double e1, double e0)
__m256 _mm256_set_ps (float e7, float e6, float e5, float e4, float e3, float e2, float e1, float e0)
__m256i _mm256_set1_epi16 (short a)
__m256i _mm256_set1_epi32 (int a)
__m256i _mm256_set1_epi64x (long long a)
__m256i _mm256_set1_epi8 (char a)
__m256d _mm256_set1_pd (double a)
__m256 _mm256_set1_ps (float a)
__m256i _mm256_setr_epi16 (short e15, short e14, short e13, short e12, short e11, short e10, short e9, short e8, short e7, short e6, short e5, short e4, short e3, short e2, short e1, short e0)
__m256i _mm256_setr_epi32 (int e7, int e6, int e5, int e4, int e3, int e2, int e1, int e0)
__m256i _mm256_setr_epi64x (__int64 e3, __int64 e2, __int64 e1, __int64 e0)
__m256i _mm256_setr_epi8 (char e31, char e30, char e29, char e28, char e27, char e26, char e25, char e24, char e23, char e22, char e21, char e20, char e19, char e18, char e17, char e16, char e15, char e14, char e13, char e12, char e11, char e10, char e9, char e8, char e7, char e6, char e5, char e4, char e3, char e2, char e1, char e0)
__m256 _mm256_setr_m128 (__m128 lo, __m128 hi)
__m256d _mm256_setr_m128d (__m128d lo, __m128d hi)
__m256i _mm256_setr_m128i (__m128i lo, __m128i hi)
__m256d _mm256_setr_pd (double e3, double e2, double e1, double e0)
__m256 _mm256_setr_ps (float e7, float e6, float e5, float e4, float e3, float e2, float e1, float e0)
__m256d _mm256_setzero_pd (void)
__m256 _mm256_setzero_ps (void)
__m256i _mm256_setzero_si256 (void)
返回带有未定义元素的__m256d类型的向量。
__m256d _mm256_undefined_pd (void)
__m256 _mm256_undefined_ps (void)
__m256i _mm256_undefined_si256 (void)
将所有XMM或YMM寄存器的内容归零。
void _mm256_zeroall (void)
将所有YMM寄存器的高128位归零; 寄存器的低128位未经修改。
void _mm256_zeroupper (void)
十四、使用imm8中的高4位有条件地将a和b中的打包单精度(32位)浮点元素相乘,将四个乘积相加,并使用imm8的低4位有条件地将总和存储在dst中。
__m256 _mm256_dp_ps (__m256 a, __m256 b, const int imm8)
十五、计算a和b中128位(表示双精度(64位)浮点元素)的按位AND,产生中间128位值,如果每个64位元素的符号位,则将ZF设置为1 中间值为零,否则将ZF设置为0.计算a的按位NOT,然后用b计算AND,产生一个中间值,如果中间值中每个64位元素的符号位为,则将CF设置为1 为零,否则将CF设置为0.返回CF值。
int _mm_testc_pd (__m128d a, __m128d b)
tmp[127:0] := a[127:0] AND b[127:0]
IF (tmp[63] == tmp[127] == 0)
ZF := 1
ELSE
ZF := 0
FI
tmp[127:0] := (NOT a[127:0]) AND b[127:0]
IF (tmp[63] == tmp[127] == 0)
CF := 1
ELSE
CF := 0
FI
dst := CF
int _mm256_testc_pd (__m256d a, __m256d b)
int _mm_testc_ps (__m128 a, __m128 b)
int _mm256_testc_ps (__m256 a, __m256 b)
int _mm256_testc_si256 (__m256i a, __m256i b)
int _mm_testnzc_pd (__m128d a, __m128d b)
int _mm256_testnzc_pd (__m256d a, __m256d b)
int _mm_testnzc_ps (__m128 a, __m128 b)
int _mm256_testnzc_ps (__m256 a, __m256 b)
int _mm256_testnzc_si256 (__m256i a, __m256i b)
int _mm_testz_pd (__m128d a, __m128d b)
int _mm256_testz_pd (__m256d a, __m256d b)
int _mm_testz_ps (__m128 a, __m128 b)
int _mm256_testz_ps (__m256 a, __m256 b)
int _mm256_testz_si256 (__m256i a, __m256i b)
十六、从a和b中的每个128位通道的高半部分解压缩并交错双精度(64位)浮点元素,并将结果存储在dst中。
__m256d _mm256_unpackhi_pd (__m256d a, __m256d b)
DEFINE INTERLEAVE_HIGH_QWORDS(src1[127:0], src2[127:0])
dst[63:0] := src1[127:64]
dst[127:64] := src2[127:64]
RETURN dst[127:0]
dst[127:0] := INTERLEAVE_HIGH_QWORDS(a[127:0], b[127:0])
dst[255:128] := INTERLEAVE_HIGH_QWORDS(a[255:128], b[255:128])
dst[MAX:256] := 0
__m256 _mm256_unpackhi_ps (__m256 a, __m256 b)
__m256d _mm256_unpacklo_pd (__m256d a, __m256d b)
__m256 _mm256_unpacklo_ps (__m256 a, __m256 b)
以上是关于AVX指令使用的主要内容,如果未能解决你的问题,请参考以下文章
MSVC /arch:[指令集] - SSE3、AVX、AVX2