回答
您可以使用this question中的一種方法生成MS n 字節設置爲全1的掩碼。然後你只需要解決任何剩餘的位,當n不是8
多我建議嘗試這樣的事:
- init vector A = all (8 bit) elements to the residual mask of n % 8 bits
- init vector B = mask of n/8 bytes using one of the above-mentioned methods
- init vector C = mask of (n + 7)/8 bytes using one of the above-mentioned methods
- result = A | B & C
因此,例如,如果n = 36:
A = f0 f0 f0 f0 f0 f0 f0 f0 f0 f0 f0 f0 f0 f0 f0 f0
B = ff ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00
C = ff ff ff ff ff 00 00 00 00 00 00 00 00 00 00 00
==> ff ff ff ff f0 00 00 00 00 00 00 00 00 00 00 00
根據需要,這將是無分支的,但它可能是大約10條指令的順序。可能有更有效的方法,但我需要給這個更多的想法。
我將此添加爲第二個答案並留下歷史興趣的第一個答案。它看起來像你可以做一些更有效的與_mm_slli_epi64
:
#include <emmintrin.h>
#include <stdio.h>
__m128i bit_mask(int n)
{
__m128i v0 = _mm_set_epi64x(-1, -(n > 64)); // AND mask
__m128i v1 = _mm_set_epi64x(-(n > 64), 0); // OR mask
__m128i v2 = _mm_slli_epi64(_mm_set1_epi64x(-1), (128 - n) & 63);
v2 = _mm_and_si128(v2, v0);
v2 = _mm_or_si128(v2, v1);
return v2;
}
int main(int argc, char *argv[])
{
int n = 36;
if (argc > 1) n = atoi(argv[1]);
printf("bit_mask(%3d) = %02vx\n", n, bit_mask(n));
return 0;
}
測試:
$ gcc -Wall -msse2 sse_bit_mask.c
$ for n in 1 2 3 63 64 65 127 128 ; do ./a.out $n ; done
bit_mask( 1) = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80
bit_mask( 2) = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 c0
bit_mask( 3) = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 e0
bit_mask(63) = 00 00 00 00 00 00 00 00 fe ff ff ff ff ff ff ff
bit_mask(64) = 00 00 00 00 00 00 00 00 ff ff ff ff ff ff ff ff
bit_mask(65) = 00 00 00 00 00 00 00 80 ff ff ff ff ff ff ff ff
bit_mask(127) = fe ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
bit_mask(128) = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
這看起來並不好 - 65和127的結果是不正確的。我錯過了什麼嗎? –
對不起 - 我現在意識到我需要兩個面具,而不是一個。它現在似乎正在工作。 –
@PaulR,printf中的%vx選項是什麼?這打印SSE寄存器?哪個編譯器? http://coliru.stacked-crooked.com/a/b8fd938a10e98b17 –
- 1. SSE 64位寄存器
- 2. 解釋GDB寄存器(SSE寄存器)
- 3. 在SSE寄存器(GCC,C++)
- 4. 加載SSE寄存器
- 5. 如何設置寄存器中的位?
- 6. 設置陣列中的最後N位
- 7. SSE設置寄存器爲0.0和1.0的最佳方法是什麼?
- 8. 轉換8 16位SSE寄存器8位數據
- 9. 將向量載入SSE寄存器
- 10. 使用新的sse寄存器xmm8 - xmm15
- 11. 訪問一個SSE寄存器變量
- 12. 轉換8位SSE寄存器,以16個短褲
- 13. SSE無符號/符號的16位寄存器減法
- 14. 爲什麼SSE指令保留YMM寄存器的高128位?
- 15. 在SSE寄存器中隨機亂序偶數和奇數
- 16. 將寄存器中的位數設置爲0的計數
- 17. WRMSR在x86_64 64位RCX寄存器的值被設置錯誤
- 18. 如何在長模式下設置CR3寄存器(64位)
- 19. 位屏蔽位寄存器
- 20. 我可以將存儲在_m128 SSE寄存器中的浮點數直接移動到正常寄存器嗎?
- 21. 32位寄存器作爲8位寄存器
- 22. 將兩個x86 32位寄存器存儲到128位xmm寄存器中
- 23. 高效地將YMM寄存器的最低64位設置爲常量
- 24. 在寄存器中反轉位Thumb-2
- 25. 在寄存器中按值轉換位
- 26. 在Ride7 IDE的寄存器窗口的每行設置默認寄存器
- 27. 展位乘法器在64位寄存器的高32位中放置1
- 28. 在硬件外設中設置寄存器
- 29. 從SSE中提取_m128i寄存器的非零值
- 30. 數據何時在SSE寄存器和堆棧之間移動?
你的意思是在每個元素在整個128位向量n個MS位,或n MS位矢量? –
問題已更新。在整個矢量 – user46317
謝謝 - 大概'n'可以採取任何價值,即它不是一個方便的價值,像8的倍數? –