首页 > 后端开发 > C++ > 如何使用 SSE/AVX 指令在双精度浮点型和 64 位整数之间高效转换?

如何使用 SSE/AVX 指令在双精度浮点型和 64 位整数之间高效转换?

Barbara Streisand
发布: 2024-12-08 03:02:15
原创
467 人浏览过

How Can I Efficiently Convert Between Double-Precision Floats and 64-bit Integers Using SSE/AVX Instructions?

使用 SSE/AVX 进行高效 Double/int64 转换

SSE2 提供用于在单精度浮点和 32 位整数之间转换向量的内在函数,但缺少双精度浮点和 64 位整数的直接对应项。 AVX 也不提供这些转换。

模拟内在函数的方法

1.对于有限值:

如果可以容忍某些限制,只需两条语句即可执行 double 和 int64 之间的转换:

  • double -> ; uint64_t:

    __m128i double_to_uint64(__m128d x){
      x = _mm_add_pd(x, _mm_set1_pd(0x0010000000000000));
      return _mm_xor_si128(
          _mm_castpd_si128(x),
          _mm_castpd_si128(_mm_set1_pd(0x0010000000000000))
      );
    }
    登录后复制
  • 双 -> int64_t:

    __m128i double_to_int64(__m128d x){
      x = _mm_add_pd(x, _mm_set1_pd(0x0018000000000000));
      return _mm_sub_epi64(
          _mm_castpd_si128(x),
          _mm_castpd_si128(_mm_set1_pd(0x0018000000000000))
      );
    }
    登录后复制
  • uint64_t ->双:

    __m128d uint64_to_double(__m128i x){
      x = _mm_or_si128(x, _mm_castpd_si128(_mm_set1_pd(0x0010000000000000)));
      return _mm_sub_pd(_mm_castsi128_pd(x), _mm_set1_pd(0x0010000000000000));
    }
    登录后复制
  • int64_t ->双:

    __m128d int64_to_double(__m128i x){
      x = _mm_add_epi64(x, _mm_castpd_si128(_mm_set1_pd(0x0018000000000000)));
      return _mm_sub_pd(_mm_castsi128_pd(x), _mm_set1_pd(0x0018000000000000));
    }
    登录后复制

2。全范围 int64 -> double:

要将全范围 int64 转换为 double,uint64_t 需要 5 条指令,int64_t 需要 6 条指令:

  • uint64_t -> ;双:

    __m128d uint64_to_double_full(__m128i x){
      __m128i xH = _mm_srli_epi64(x, 32);
      xH = _mm_or_si128(xH, _mm_castpd_si128(_mm_set1_pd(19342813113834066795298816.)));          //  2^84
      __m128i xL = _mm_blend_epi16(x, _mm_castpd_si128(_mm_set1_pd(0x0010000000000000)), 0xcc);   //  2^52
      __m128d f = _mm_sub_pd(_mm_castsi128_pd(xH), _mm_set1_pd(19342813118337666422669312.));     //  2^84 + 2^52
      return _mm_add_pd(f, _mm_castsi128_pd(xL));
    }
    登录后复制
  • int64_t -> double:

    __m128d int64_to_double_full(__m128i x){
      __m128i xH = _mm_srai_epi32(x, 16);
      xH = _mm_blend_epi16(xH, _mm_setzero_si128(), 0x33);
      xH = _mm_add_epi64(xH, _mm_castpd_si128(_mm_set1_pd(442721857769029238784.)));              //  3*2^67
      __m128i xL = _mm_blend_epi16(x, _mm_castpd_si128(_mm_set1_pd(0x0010000000000000)), 0x88);   //  2^52
      __m128d f = _mm_sub_pd(_mm_castsi128_pd(xH), _mm_set1_pd(442726361368656609280.));          //  3*2^67 + 2^52
      return _mm_add_pd(f, _mm_castsi128_pd(xL));
    }
    登录后复制

AVX512

AVX512 确实提供与 64 位整数(有符号和无符号)之间的直接转换签署了。这些转换是使用 _mm512_cvtpd_epi64 和 _mm256_cvtpd_epi64 等内在函数完成的。

请注意,这些解决方案不以完整代码形式提供。读者应完成它们并根据需要进行优化,以使它们适应特定的上下文。

以上是如何使用 SSE/AVX 指令在双精度浮点型和 64 位整数之间高效转换?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板