如何仅使用 SSE2 在双精度中地板/整数

How to floor/int in double using only SSE2?

本文关键字:整数 双精度 何仅使 SSE2      更新时间:2023-10-16

float中,似乎很容易floor(),并且比int(),例如:

float z = floor(LOG2EF * x + 0.5f);
const int32_t n = int32_t(z);   

成为:

__m128 z = _mm_add_ps(_mm_mul_ps(log2ef, x), half);
__m128 t = _mm_cvtepi32_ps(_mm_cvttps_epi32(z));
z = _mm_sub_ps(t, _mm_and_ps(_mm_cmplt_ps(z, t), one));
__m128i n = _mm_cvtps_epi32(z);

但是,如何在仅使用 SSE2 的double中实现这一目标?

这是我想转换的双重版本:

double z = floor(LOG2E * x + 0.5);
const int32_t n = int32_t(z);

只需使用单精度...ps...)固有的双精度等效(...pd...):

__m128i n = _mm_cvtpd_epi32(z);

根据英特尔内部函数指南,该内部函数确实可用于 SSE2:https://software.intel.com/sites/landingpage/IntrinsicsGuide/#expand=4966,1917&techs=SSE2

__m128i _mm_cvtpd_epi32 (__m128d a)

将打包的双精度(64 位)浮点元素转换为 a 中的打包 32 位整数,并将结果存储在 dst 中。

FOR j := 0 to 1
  i := 32*j
  k := 64*j
  dst[i+31:i] := Convert_FP64_To_Int32(a[k+63:k])
ENDFOR