如何在 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 < CHAR_BIT, j++) printf("%hhu", (bytearray[i] & (1 << 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?