簡體   English   中英

移位n位的__m128i

[英]Shift a __m128i of n bits

我有一個__m128i變量,我需要將其n位的128位值移位,即_mm_srli_si128_mm_slli_si128工作,但是在位而不是字節上。 這樣做最有效的方法是什么?

對於使用SSE2進行左/右立即換檔,這是我能想到的最好的:

#include <stdio.h>
#include <emmintrin.h>

#define SHL128(v, n) \
({ \
    __m128i v1, v2; \
 \
    if ((n) >= 64) \
    { \
        v1 = _mm_slli_si128(v, 8); \
        v1 = _mm_slli_epi64(v1, (n) - 64); \
    } \
    else \
    { \
        v1 = _mm_slli_epi64(v, n); \
        v2 = _mm_slli_si128(v, 8); \
        v2 = _mm_srli_epi64(v2, 64 - (n)); \
        v1 = _mm_or_si128(v1, v2); \
    } \
    v1; \
})

#define SHR128(v, n) \
({ \
    __m128i v1, v2; \
 \
    if ((n) >= 64) \
    { \
        v1 = _mm_srli_si128(v, 8); \
        v1 = _mm_srli_epi64(v1, (n) - 64); \
    } \
    else \
    { \
        v1 = _mm_srli_epi64(v, n); \
        v2 = _mm_srli_si128(v, 8); \
        v2 = _mm_slli_epi64(v2, 64 - (n)); \
        v1 = _mm_or_si128(v1, v2); \
    } \
    v1; \
})

int main(void)
{
    __m128i va = _mm_setr_epi8(0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f);
    __m128i vb, vc;

    vb = SHL128(va, 4);
    vc = SHR128(va, 4);

    printf("va = %02vx\n", va);
    printf("vb = %02vx\n", vb);
    printf("vc = %02vx\n", vc);
    printf("\n");

    vb = SHL128(va, 68);
    vc = SHR128(va, 68);

    printf("va = %02vx\n", va);
    printf("vb = %02vx\n", vb);
    printf("vc = %02vx\n", vc);

    return 0;
}

測試:

$ gcc -Wall -msse2 shift128.c && ./a.out
va = 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
vb = 00 10 20 30 40 50 60 70 80 90 a0 b0 c0 d0 e0 f0
vc = 10 20 30 40 50 60 70 80 90 a0 b0 c0 d0 e0 f0 00

va = 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
vb = 00 00 00 00 00 00 00 00 00 10 20 30 40 50 60 70
vc = 90 a0 b0 c0 d0 e0 f0 00 00 00 00 00 00 00 00 00
$ 

請注意,SHL128 / SHR128宏是使用gcc,clang和其他一些編譯器支持的gcc擴展實現的,但如果編譯器不支持此擴展,則需要對這些宏進行調整。

另請注意,測試工具中使用的SIMD類型的printf擴展適用於Apple gcc,clang ,但如果您的編譯器不支持此功能並且您想要測試代碼,那么您需要實現自己的SIMD打印例程。

關於性能的注意事項 - if / else分支將被優化,只要n是編譯時常量(對於移位內在函數它無論如何都需要),因此你有2條指令用於n> = 64的情況和4條指令對於n <64的情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM