SSE 内部函数位向右移动
SSE intrinsics bit shifting to the right
我正在尝试使用内部函数将整数向右位移。下面的代码尝试这样做,但输出看起来不像预期的那样,也许我加载了错误的数字或使用错误的内在函数。下面是输出:
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
我确实尝试查看此线程,但这甚至没有尝试将位移指令与 SSE 内部函数一起使用。
下面是完整的代码(使用 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;
}
当您使用 _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 个字节,你得到
0x00804020100804020180402010080402
当您读取单个字节值时,byte[0] 是最低有效字节,这将是最右边的字节。(所以它打印02 04 08等...
其他语句也是如此,尽管我认为您希望在print_4_num
函数内部进行uint32_t*
而不是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/
相关文章:
- 为什么在这种情况下调用非常量右值移动构造函数?
- 右移布尔值在C++
- C++模板成员初始化:用右值移动构造,但用左值移动引用
- 何时右移操作>>移位符号位,何时不?
- 这个右移是如何工作的:字符串流>>无符号的int>>无符号的int?
- C++中的负数右移运算符
- C++ 尝试将数字右移 32 会得到两种不同的结果
- 对已签名数据进行逻辑右移
- 右移速度与左移相同的速度测试位
- 右移无法正常工作
- 为什么将 int a=1 移到左 31 位然后向右移 31 位,它变成 -1
- 当 b 大于 a 中的位数时右移(a >> b)的未定义行为?
- 为什么无符号的 int 右移总是用"1"填充
- 重载左移和右移运算符(cin和cout)
- 在c++中,取一个整数数组(arr[])、其长度(N)和元素数右移(M):
- 右移g++时出现意外结果
- 如果计数大于类型的宽度,则为右移未定义的行为
- 使用左移或右移计算对数基数 n
- static_assert签名的右移具有两个补码行为是否合法?
- 在C/C++中,左移或右移零点实际上会生成一条指令