如何在 C 中打印 __m128i 变量的位?

Posted

技术标签:

【中文标题】如何在 C 中打印 __m128i 变量的位?【英文标题】:How can I print the bits of a __m128i variable in C? 【发布时间】:2017-05-08 20:29:55 【问题描述】:

我不知道如何在 C 中打印 __m128i 变量的位 所以请随时告诉我你的想法!

谢谢!

【问题讨论】:

请尝试一下,如果它不起作用,请发布代码,并提出适当的问题。 你可以使用一个简单的循环,每次迭代提取高位,打印它,然后将二进制值左移一位。 【参考方案1】:

无论如何,这将是一个可怕的 hack。在我的脑海中(__m128i 是一个 128 位/ 16 字节对齐的类型)我可以想到这个:

__m128i toPrint;
char * bytearray = (char *) &toPrint;
for(int i = 0; i < 16; i++) printf("%02hhx", bytearray[i]);

这会以十六进制打印,但很难看。

【讨论】:

工作正常,但我不喜欢十六进制输出。 好吧,如果您出于某种原因需要二进制文件,则将上面的 printf 调用替换为更丑陋的嵌套循环,如下所示:for(int j = 0; j &lt; CHAR_BIT, j++) printf("%hhu", (bytearray[i] &amp; (1 &lt;&lt; j)) ? 1 : 0);【参考方案2】:

为了打印这些位,我实现了以下程序。

//Linx-mint 18.1, gcc 6.2, Skylake.
#include <x86intrin.h>
#include <stdio.h>


void printVec8(__m128i vec)

    int i;
    char array[16];
    _mm_store_si128( (__m128i *) array, vec);
    for(i=0; i<16; i++)
        printf("%3u , " , array[i]);
    
    printf("\n");


inline void vec_print_128Bits(__m128i vec)

    __m128i bit0, bit1, bit2, bit3, bit4, bit5, bit6, bit7;
    __m128i mask = _mm_set_epi8(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1);
    //fisrt separate them and print to check them:
    bit0 = _mm_and_si128(vec , mask);                   printf("bit0 :"); printVec8(bit0);
    bit1 = _mm_and_si128(_mm_srai_epi16(vec,1) , mask); printf("bit1 :"); printVec8(bit1);
    bit2 = _mm_and_si128(_mm_srai_epi16(vec,2) , mask); printf("bit2 :"); printVec8(bit2);
    bit3 = _mm_and_si128(_mm_srai_epi16(vec,3) , mask); printf("bit3 :"); printVec8(bit3);
    bit4 = _mm_and_si128(_mm_srai_epi16(vec,4) , mask); printf("bit4 :"); printVec8(bit4);
    bit5 = _mm_and_si128(_mm_srai_epi16(vec,5) , mask); printf("bit5 :"); printVec8(bit5);
    bit6 = _mm_and_si128(_mm_srai_epi16(vec,6) , mask); printf("bit6 :"); printVec8(bit6);
    bit7 = _mm_and_si128(_mm_srai_epi16(vec,7) , mask); printf("bit7 :"); printVec8(bit7);

    //now store them in array
    char bits[8][16];
    _mm_store_si128( (__m128i *) bits[0], bit0);
    _mm_store_si128( (__m128i *) bits[1], bit1);
    _mm_store_si128( (__m128i *) bits[2], bit2);
    _mm_store_si128( (__m128i *) bits[3], bit3);
    _mm_store_si128( (__m128i *) bits[4], bit4);
    _mm_store_si128( (__m128i *) bits[5], bit5);
    _mm_store_si128( (__m128i *) bits[6], bit6);
    _mm_store_si128( (__m128i *) bits[7], bit7);

    //and now print them all:
    int i, j;
    printf("all bits : \n");
    for(i=0; i<16; i++)
        for( j=7; j>=0; j--)
        
            printf("%u ", bits[j][i]);
        
        //printf("\n");
    




int main()



    __m128i vec = _mm_setr_epi8(0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F); printf("vec  :"); printVec8(vec);

    vec_print_128Bits(vec); 


    return 0;

输出是:

vec  :  0 ,   1 ,   2 ,   3 ,   4 ,   5 ,   6 ,   7 ,   8 ,   9 ,  10 ,  11 ,  12 ,  13 ,  14 ,  15 , 
bit0 :  0 ,   1 ,   0 ,   1 ,   0 ,   1 ,   0 ,   1 ,   0 ,   1 ,   0 ,   1 ,   0 ,   1 ,   0 ,   1 , 
bit1 :  0 ,   0 ,   1 ,   1 ,   0 ,   0 ,   1 ,   1 ,   0 ,   0 ,   1 ,   1 ,   0 ,   0 ,   1 ,   1 , 
bit2 :  0 ,   0 ,   0 ,   0 ,   1 ,   1 ,   1 ,   1 ,   0 ,   0 ,   0 ,   0 ,   1 ,   1 ,   1 ,   1 , 
bit3 :  0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   1 ,   1 ,   1 ,   1 ,   1 ,   1 ,   1 ,   1 , 
bit4 :  0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 , 
bit5 :  0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 , 
bit6 :  0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 , 
bit7 :  0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 , 
all bits : 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 1 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 1 0 1 0 0 0 0 0 1 0 1 1 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 1 0 0 0 0 1 1 1 0 0 0 0 0 1 1 1 1 

【讨论】:

第一部分(直到//现在将它们存储在数组中)工作正常。其余的给我一个错误.. @Sofia,请改用_mm_storeu_si128,告诉我错误是否消失。【参考方案3】:

打印__m128i整数值的所有128位的递归函数。

// Private helper function
static void print_128_bitsH(__m128i val, int depth)

    if (depth > 0)
        print_128_bitsH(val >> 1, depth - 1);
    printf("%d", (int)(val & 1));


// Print 128 bits, from most significant to least significant
void print_128_bits(__m128i val)

    print_128_bitsH(val, 128);
    printf("\n");

【讨论】:

这比我的例子干净多了。 这也可以在单个函数中用一个循环来完成,但是递归的解决方案更容易理解。【参考方案4】:

这与打印 32 位整数的位实际上并没有太大区别。将 128 位向量存储为四个 32 位整数,然后按顺序打印每个整数的位。

void print_bits128(__m128i v) 
  int t[4];
  _mm_storeu_si128((__m128i*)t, v);
  for(int i=0; i<4; i++) 
    int num = t[i];
    for(int j=0; j<32; j++)
      printf("%u",num&0x80000000 ? 1 : 0);
      num <<= 1;
    
  
  puts("");

【讨论】:

以上是关于如何在 C 中打印 __m128i 变量的位?的主要内容,如果未能解决你的问题,请参考以下文章

两个 __m128i 的两个位到一个 __m128i 的四个位 -SSE

如何在 MSVC 中高效地将两个 __m128d 转换为一个 __m128i?

SSE:如何将 _m128i._i32[4] 减少到 _m128i._i8

如何在 gcc 中静态初始化 __m128i 数组?

如何在 MASM 中声明 __m128i 常量?

从 __m128i 中查找最小值/最大值