2014-04-02 65 views
3

如何創建一個,其中n最高有效位已設置(在整個向量中)?我需要這個來掩蓋與計算相關的緩衝區的部分。如果可能,解決方案應該沒有分支,但這似乎很難實現在SSE寄存器中設置最後或前n位

我該怎麼做?

+0

你的意思是在每個元素在整個128位向量n個MS位,或n MS位矢量? –

+0

問題已更新。在整個矢量 – user46317

+0

謝謝 - 大概'n'可以採取任何價值,即它不是一個方便的價值,像8的倍數? –

回答

1

您可以使用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條指令的順序。可能有更有效的方法,但我需要給這個更多的想法。

3

我將此添加爲第二個答案並留下歷史興趣的第一個答案。它看起來像你可以做一些更有效的與_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 
+0

這看起來並不好 - 65和127的結果是不正確的。我錯過了什麼嗎? –

+1

對不起 - 我現在意識到我需要兩個面具,而不是一個。它現在似乎正在工作。 –

+0

@PaulR,printf中的%vx選項是什麼?這打印SSE寄存器?哪個編譯器? http://coliru.stacked-crooked.com/a/b8fd938a10e98b17 –