我想使用 AVX2 添加 2 個無符號向量
__m256i i1 = _mm256_loadu_si256((__m256i *) si1);
__m256i i2 = _mm256_loadu_si256((__m256i *) si2);
__m256i result = _mm256_adds_epu16(i2, i1);
但是我需要溢位而不是飽和_mm256_adds_epu16與非矢量化代碼相同,有什么解決方案嗎?
uj5u.com熱心網友回復:
使用正常的二進制包裝_mm256_add_epi16而不是 saturating adds。
二進制補碼和無符號加/減是相同的二進制運算,這就是現代計算機使用二進制補碼的原因之一。作為提及的asm 手冊條目vpaddw,這些說明可用于有符號或無符號整數。(內在函式指南條目根本沒有提到簽名,因此在消除這種混淆方面沒有多大幫助。)
比較 like_mm_cmpgt_epi32對符號敏感,但數學運算 (and cmpeq) 不敏感。
英特爾選擇的內在函式名稱可能看起來像是專門用于有符號整數,但它們總是使用epiorsi用于在有符號和無符號元素上同樣有效的東西。但是不,epu意味著一個特別未簽名的東西,而epi可以是特別簽名的操作,或者可以是在有符號或無符號上同樣作業的東西。或者與簽名無關的事情。
例如,_mm_and_si128是純按位。 _mm_srli_epi32是一個邏輯右移,在零中移動,就像一個無符號的 C 移位。不是符號位的副本,那是_mm_srai_epi32(立即右移算術)。洗牌就像_mm_shuffle_epi32只是在塊中移動資料。
非擴展乘法_mm_mullo_epi16和_mm_mullo_epi32有符號或無符號的乘法也相同。只有高半_mm_mulhi_epu16或擴大的乘法_mm_mul_epu32具有未簽名的形式作為其專門簽名epi16/32形式的對應物。
這也是為什么 386 只添加了一個標量整數imul ecx, esi形式,而不是 a mul ecx, esi,因為只有 FLAGS 設定會有所不同,而不是整數結果。SIMD 操作甚至沒有 FLAGS 輸出。
內在函式指南無益地描述_mm_mullo_epi16為符號擴展并產生 32 位產品,然后截斷到低 32 位。asm 手冊pmullw也將其描述為已簽名的方式,似乎將其作為已簽名的伴侶來談論pmulhw。(并且有一些錯誤,例如將 AVX1VPMULLW xmm1, xmm2, xmm3/m128形式描述為乘以 32 位 dword 元素,可能是來自 的復制/粘貼錯誤pmulld)
有時英特爾的命名方案是有限的,比如_mm_maddubs_epi16u8 x i8 => 16 位擴展乘法,水平添加對(有符號飽和)。我通常必須查找內在函式pmaddubsw來提醒自己他們以輸出元素寬度而不是輸入來命名它。輸入有不同的符號,所以如果他們必須選擇一個,邊,我想為輸出命名是有意義的,有符號飽和可能發生在某些輸入上,比如 for pmaddwd。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/477238.html
