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

来源:互联网 发布:java是面向对象的吗 编辑:程序博客网 时间:2024/06/05 05:49
  • _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.
阅读全文
0 0
原创粉丝点击