我尝试使用内在函数将整数移位到右侧。下面的代码尝试这样做,但输出看起来并不像预期,也许我没有错误地加载数字或使用错误的内在函数。这是输出:
2 4 8 16 32 64 128 1 2 4 8 16 32 64 128 0
512 1024 2048 4096 8192 16384 32768 0
0 8192 0 16384
8 0 16 0
我确实尝试过查看thread,但即便尝试使用bitshift instructions with SSE intrinsics。
这里是完整的代码(使用SSE2标志编译)。
#include <emmintrin.h>
#include <stdio.h>
#include <stdint.h>
void print_16_num(__m128i var)
{
uint8_t *val = (uint8_t*) &var;
printf(" %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i \n",
val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7],val[8], val[9], val[10], val[11], val[12], val[13], val[14], val[15]);
}
void print_8_num( __m128i var)
{
uint16_t *val = (uint16_t*) &var;
printf(" %i %i %i %i %i %i %i %i \n",
val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7]);
}
void print_4_num( __m128i var)
{
uint16_t *val = (uint16_t*) &var;
printf(" %i %i %i %i \n",
val[0], val[1], val[2], val[3]);
}
int main()
{
__m128i _16 = _mm_set_epi8( 128, 64, 32, 16, 8, 4, 2, 1, 128, 64, 32, 16, 8, 4, 2, 1);
print_16_num(_mm_srli_si128(_16,1));
__m128i _8 = _mm_set_epi16( 128, 64, 32, 16, 8, 4, 2, 1);
print_8_num( _mm_srli_si128(_8,1));
__m128i _4 = _mm_set_epi32( 128, 64, 32, 16);
print_4_num( _mm_srli_si128(_4,1));
_4 = _mm_set_epi32( 128, 64, 32, 16);
print_4_num( _mm_srli_epi32(_4,1));
return 0;
}
答案 0 :(得分:4)
当您使用_mm_set_epi *函数时,它们首先接受它们的参数作为最重要的项目。
例如,第一个声明,
__m128i _16 = _mm_set_epi8( 128, 64, 32, 16, 8, 4, 2, 1, 128, 64, 32, 16, 8, 4, 2, 1);
将使用以下值加载变量:
0x80402010080402018040201008040201
(128,64,32 ...)
然后你用_mm_srli_si128(_16,1)
将那个128位值右移1 byte 然后你得到
0x00804020100804020180402010080402
当您读取单个字节值时,byte [0]是最低有效字节,它是最右边的字节。 (所以它打印02 04 08等...)
其他陈述也是如此,虽然我认为你想在uint32_t*
函数内转换为print_4_num
而不是uint16_t*
。
对于最后一个,_mm_srli_epi32(_4,1)
将移动值
0x00000080000000400000002000000010
(128) (64) (32) (16)
一次,它将成为
0x00000040000000200000001000000008
但它将打印“8 0 16 0”,因为您正在读取print_4_num
函数中的16位值而不是32位值:
0x0000 0040 0000 0020 0000 0010 0000 0008
(not used) [3] [2] [1] [0]
要查看哪些功能可以轻松完成,请查看“英特尔内部指南”:
https://software.intel.com/sites/landingpage/IntrinsicsGuide/