SSE指令 intrinsic函数总结(持续更新...)

0 篇文章 0 订阅
  • _mm_cvtps_epi32 :Converts the four single-precision, floating-point values of a to signed 32-bit integer values. 意思是: 把四个float变量强转为四个int变量。其中需要注意的是他的截断规则:四舍五入,在进位后末位是偶数的进,否则不进位。
  • _mm_cvttps_epi32: Converts the four single-precision, floating-point values of a to signed 32-bit integer values using truncate. 这里就多了using truncate,意思是直接截断。与C/C++中的 r = (int)a 一样。
 使用案例: 
 __m128 test1 = _mm_set_ps(3.4f, 3.5f, 3.6f, 4.5f);
 __m128i test2 = _mm_cvtps_epi32(test1);
 __m128i test3 = _mm_cvttps_epi32(test1);
 输出结果分别: 3(高位),444(低位) 和 3(高位),334(低位)

但是需要注意的是一个浮点数和int32数的表示范围的问题:因为浮点数的表示范围大于int32, float型数据的绝对值在2^128(近似10^38)级,而int32在 -2147483648~2147483647,所以,若:
__m128 test1 = _mm_set_ps(3.4f, 3.5f, 3.6f, 2147483647.5f);
__m128i test2 = _mm_cvtps_epi32(test1);
__m128i test3 = _mm_cvttps_epi32(test1);
则,输出结果分别为:3(高位),33, -2147483648(低位) 和 3(高位),44, -2147483648(低位)
若set  2147483646.5f, 对应的仍为-2147483648(低位),甚至2147483640.5f也是-2147483648(低位)

但是,若set 1999999999.3f
__m128 test1 = _mm_set_ps(3.4f, 3.5f, 3.6f, 1999999999.3f);
输出结果:3(高位),33, 2000000000(低位)和3(高位),44, 2000000000(低位); 小数点后为3,不管是_mm_cvtps_epi32还是截断版_mm_cvttps_epi32都进了以为得到2000000000. 
有点诡异,这或许与浮点数本身的精度有关吧

所以综上测试,个人认为_mm_cvtps_epi32 以及_mm_cvttps_epi32的结果与浮点数的表示范围以及精度都有关系,但一般情况下,不set这么大的数,使用起来应该没有问题
  • _mm_cvtepi32_ps
//_mm_cvtepi32_ps
__m128i test1 = _mm_set_epi32(223, 2147483647, 2147483646, -2147483647);
__m128 test2 = _mm_cvtepi32_ps(test1);
输出:223.000000(高位), 2.14748365e+009, 2.14748365e+009, -2.14748365e+009(低位)
由于浮点数的表示范围大于int32,所以,_mm_cvtepi32_ps可以正常转换.(-2147483648编译不过去)

**以上实验只是为了研究下边界条件,但是一般情况下,正确的做法是考虑所处理问题的数据范围,再来决定使用什么类型的数据以及数据类型的转换**
  • _mm_cvtepu32_epi64: Zero extend packed unsigned 32-bit integers in a to packed 64-bit integers, and store the results in dst.
__m128i test1 = _mm_set_epi32(223, 8088, 2147483646, 2147483647);
__m128i test2 = _mm_cvtepu32_epi64(test1);
输出:2147483646(高位), 2147483647(低位)
---------------------------------------------------------------------
//intValues:A 128-bit parameter that contains two unsigned 32-bit integers  
//in the lower 64 bits, intValues=(a0, a1, a2, a3)  
/*则r0 = a0 
    r1 = 0 
    r2 = a1 
    r3 = 0*/  
extern __m128i _mm_cvtepu32_epi64(__m128i intValues); 
  • _mm_cvtepi32_epi64: Sign extend packed 32-bit integers in a to packed 64-bit integers, and store the results in dst.
extern __m128i _mm_cvtepi8_epi64 (__m128i byteValues);   
//intValues: A 128-bit parameter that contains two signed 32-bit   
//integers in the lower 64 bits, intValues=(a0, a1, a2, a3)  
/*则r0 := a0 
    r1 := (a0 < 0) ? 0xffffffff : 0 
    r2 := a1 
    r3 := (a1 < 0) ? 0xffffffff : 0*/  
extern __m128i _mm_cvtepi32_epi64(__m128i intValues);  

貌似没有 epixx To epuxx 的 inrinsic 函数

  • int _mm_cvtsi128_si32 (__m128i a) : Copy the lower 32-bit integer in a to dst. 只取低位32-bits进行转换,也只返回低位32-bits.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值