AVX編程基礎
一、數據類型
數據類型 | 描述 |
---|---|
__m128 | 包含4個float類型數字的向量 |
__m128d | 包含2個double類型數字的向量 |
__m128i | 包含若干個整型數字的向量 |
__m256 | 包含8個float類型數字的向量 |
__m256d | 包含4個double類型數字的向量 |
__m256i | 包含若干個整型數字的向量 |
- 每一種類型,從2個下劃線開頭,接一個m,然後是vector的位長度。
- 如果向量類型是以d結束的,那麼向量裏面是double類型的數字。如果沒有後綴,就代表向量只包含float類型的數字。
- 整形的向量可以包含各種類型的整形數,例如char,short,unsigned long long。也就是說,__m256i可以包含32個char,16個short類型,8個int類型,4個long類型。這些整形數可以是有符號類型也可以是無符號類型。
二、函數命名約定
_mm<bit_width>_<name>_<data_type>
<bit_width>
表明了向量的位長度,對於128位的向量,這個參數爲空,對於256位的向量,這個參數爲256。<name>
描述了內聯函數的算術操作。<data_type>
標識函數主參數的數據類型。
-ps 包含float類型的向量
pd 包含double類型的向量
epi8/epi16/epi32/epi64 包含8位/16位/32位/64位的有符號整數
epu8/epu16/epu32/epu64 包含8位/16位/32位/64位的無符號整數
si128/si256 未指定的128位或者256位向量
m128/m128i/m128d/m256/m256i/m256d 當輸入向量類型與返回向量的類型不同時,標識輸入向量類型
三、用標量值初始化
數據類型 | 描述 |
---|---|
_mm256_setzero_ps/pd | 返回一個全0的float類型的向量 |
_mm256_setzero_si256 | 返回一個全0的整形向量 |
_mm256_set1_ps/pd | 用一個float類型的數填充向量 |
_mm256_set1_epi8/epi16/epi32/epi64x | 用整形數填充向量 |
_mm256_set_ps/pd | 用8個float或者4個double類型數字初始化向量 |
_mm256_set_epi8/epi16/epi32/epi64x | 用一個整形數初始化向量 |
_mm256_set_m128/m128d/m128i | 用2個128位的向量初始化一個256位向量 |
_mm256_setr_ps/pd | 用8個float或者4個double的轉置順序初始化向量 |
_mm256_setr_epi8/epi16/epi32/epi64x | 用若干個整形數的轉置順序初始化向量 |
四、從內存中加載數據
數據類型 | 描述 |
---|---|
_mm256_load_ps/pd | 從對齊的內存地址加載浮點向量 |
_mm256_load_si256 | 從對齊的內存地址加載整形向量 |
_mm256_loadu_ps/pd | 從未對齊的內存地址加載浮點向量 |
_mm256_loadu_si256 | 從未對齊的內存地址加載整形向量 |
_mm_maskload_ps/pd | 根據掩碼加載128位浮點向量的部分 |
_mm256_maskload_ps/pd | 根據掩碼加載256位浮點向量的部分 |
(2)_mm_maskload_epi32/64 | 根據掩碼加載128位整形向量的部分 |
(2)_mm256_maskload_epi32/64 | 根據掩碼加載256位整形向量的部分 |
最後2個函數前面有一個(2),代表這兩個函數只在AVX2中支持。
五、算術本質
5.1、加減法
數據類型 | 描述 |
---|---|
_mm256_add_ps/pd | 對兩個浮點向量做加法 |
_mm256_sub_ps/pd | 對兩個浮點向量做減法 |
(2)_mm256_add_epi8/16/32/64 | 對兩個整形向量做加法 |
(2)_mm256_sub_epi8/16/32/64 | 對兩個整形向量做減法 |
(2)_mm256_adds_epi8/16 (2)_mm256_adds_epu8/16 | 兩個整數向量相加且考慮內存飽和問題 |
(2)_mm256_subs_epi8/16 (2)_mm256_subs_epu8/16 | 兩個整數向量相減且考慮內存飽和問題 |
_mm256_hadd_ps/pd | 水平方向上對兩個float類型向量做加法 |
_mm256_hsub_ps/pd | 垂直方向上最兩個float類型向量做減法 |
(2)_mm256_hadd_epi16/32 | 水平方向上對兩個整形向量做加法 |
(2)_mm256_hsub_epi16/32 | 水平方向上最兩個整形向量做減法 |
(2)_mm256_hadds_epi16 | 對兩個包含short類型的向量做加法且考慮內存飽和的問題 |
(2)_mm256_hsubs_epi16 | 對兩個包含short類型的向量做減法且考慮內存飽和的問題 |
_mm256_addsub_ps/pd | 加上和減去兩個float類型的向量 |
將飽和度考慮在內的函數將結果鉗制到可以存儲的最小/最大值。沒有飽和的函數在飽和發生時忽略內存問題。
而在水平方向上做加減法的意思如下圖:
最後一個指令:_mm256_addsub_ps/pd
在偶數位置減去,奇數位置加上,獲最後得目標向量。
5.2、乘除法
數據類型 | 描述 |
---|---|
_mm256_mul_ps/pd | 對兩個float類型的向量進行相乘 |
(2)_mm256_mul_epi32 (2)_mm256_mul_epu32 | 將包含32位整數的向量的最低四個元素相乘 |
(2)_mm256_mullo_epi16/32 | Multiply integers and store low halves |
(2)_mm256_mulhi_epi16 (2)_mm256_mulhi_epu16 | Multiply integers and store high halves |
(2)_mm256_mulhrs_epi16 | Multiply 16-bit elements to form 32-bit elements |
_mm256_div_ps/pd | 對兩個float類型的向量進行想除 |
5.3、融合乘法和加法
數據類型 | 描述 |
---|---|
(2)_mm_fmadd_ps/pd/ (2)_mm256_fmadd_ps/pd | 將兩個向量相乘,再將積加上第三個。(res=a*b+c) |
(2)_mm_fmsub_ps/pd/ (2)_mm256_fmsub_ps/pd | 將兩個向量相乘,然後從乘積中減去一個向量。(res=a*b-c) |
(2)_mm_fmadd_ss/sd | 將向量中最低的元素相乘並相加(res[0]=a[0]*b[0]+c[0]) |
(2)_mm_fmsub_ss/sd | 將向量中最低的元素相乘並相減(res[0]=a[0]*b[0]-c[0]) |
(2)_mm_fnmadd_ps/pd (2)_mm256_fnmadd_ps/pd | 將兩個向量相乘,並將負積加到第三個。(res = -(a * b) + c) |
(2)_mm_fnmsub_ps/pd/ (2)_mm256_fnmsub_ps/pd | 將兩個向量相乘,並將負積加到第三個 (res = -(a * b) - c) |
(2)_mm_fnmadd_ss/sd | 將兩個向量的低位相乘,並將負積加到第三個向量的低位。(res[0] = -(a[0] * b[0]) + c[0]) |
(2)_mm_fnmsub_ss/sd | 將最低的元素相乘,並從求反的積中減去第三個向量的最低元素。(res[0] = -(a[0] * b[0]) - c[0]) |
(2)_mm_fmaddsub_ps/pd/ (2)_mm256_fmaddsub_ps/pd | 將兩個矢量相乘,然後從乘積中交替加上和減去(res=a*b+/-c) |
(2)_mm_fmsubadd_ps/pd/ (2)_mmf256_fmsubadd_ps/pd | 將兩個向量相乘,然後從乘積中交替地進行減法和加法(res=a*b-/+c)(奇數次方,偶數次方) |
六、排列和洗牌
6.1、排列
數據類型 | 描述 |
---|---|
_mm_permute_ps/pd _mm256_permute_ps/pd | 根據8位控制值從輸入向量中選擇元素 |
(2)_mm256_permute4x64_pd/ (2)_mm256_permute4x64_epi64 | 根據8位控制值從輸入向量中選擇64位元素 |
_mm256_permute2f128_ps/pd | 基於8位控制值從兩個輸入向量中選擇128位塊 |
_mm256_permute2f128_si256 | 基於8位控制值從兩個輸入向量中選擇128位塊 |
_mm_permutevar_ps/pd _mm256_permutevar_ps/pd | 根據整數向量中的位從輸入向量中選擇元素 |
(2)_mm256_permutevar8x32_ps (2)_mm256_permutevar8x32_epi32 | 使用整數向量中的索引選擇32位元素(浮點和整數) |
6.2、Shuffle
數據類型 | 描述 |
---|---|
_mm256_shuffle_ps/pd | 根據8位值選擇浮點元素 |
_mm256_shuffle_epi8/ _mm256_shuffle_epi32 | 根據8位值選擇整數元素 |
(2)_mm256_shufflelo_epi16/ (2)_mm256_shufflehi_epi16 | 基於8位控制值從兩個輸入向量中選擇128位塊 |
對於_mm256_shuffle_pd
,只使用控制值的高4位。如果輸入向量包含int或float,則使用所有控制位。對於_mm256_shuffle_ps
,前兩對位從第一個矢量中選擇元素,第二對位從第二個矢量中選擇元素。
七、參考博客
https://blog.triplez.cn/avx-avx2-learning-notes/
https://blog.csdn.net/just_sort/article/details/94393506