![](/img/trans.png)
[英]Unnecessary instructions generated for _mm_movemask_epi8 intrinsic in x64 mode
[英]How does the _mm_cmpgt_epi64 intrinsic work
我正在使用_mm_cmpgt_epi64
內在函數來實現128位加法,后來又實現了256位加法。 看着這種內在的結果,有些讓我感到困惑。
我不明白為什么計算的蒙版是這樣。
const __m128i mask = _mm_cmpgt_epi64(bflip, sumflip);
這是我的調試器中的輸出:
(lldb) p/x bflip
(__m128i) $1 = (0x00000001, 0x80000000, 0x00000000, 0x80000000)
(lldb) p/x sumflip
(__m128i) $2 = (0x00000000, 0x80000000, 0xffffffff, 0x7fffffff)
(lldb) p/x mask
(__m128i) $3 = (0xffffffff, 0xffffffff, 0x00000000, 0x00000000)
對於第一個64位通道( 63:0
),我很好。 但是,為什么第二條車道( 127:64
)也不滿?
在我看來0x8000000000000000
> 0x7fffffffffffffff
。
看來您是以32位而不是64位的形式打印它的,所以很奇怪。
但是無論如何,這是一個有符號的二進制補碼比較,如手冊中所述: http : //felixcloutier.com/x86/PCMPGTQ.html
0x8000000000000000
是最大負數的64位整數,而0x7fffffffffffffff
是最大正數。
如果要進行無符號比較,則需要通過翻轉兩個符號位來對它們進行范圍移位。 從邏輯上講,這是從0..2 ^ 64-1減去2 ^ 63到-2 ^ 63 .. 2 ^ 63-1。 但是我們可以使用更高效的XOR來完成此操作,因為XOR是不帶進位的加法,並且進位/借位不在寄存器的末尾。
const __m128i rangeshift = _mm_set1_epi64x(0x8000000000000000);
const __m128i mask = _mm_cmpgt_epi64(_mm_xor_si128(bflip, rangeshift), _mm_xor_si128(sumflip, rangeshift));
或使用AVX512F __mmask8 _mm512_cmp[eq|ge|gt|le|lt|neq]_epu64_mask( __m512i a, __m512i b)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.