Как превратить пол / int в двойной, используя только SSE2? - PullRequest
0 голосов
/ 28 января 2019

В 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);

Но как бы вы достиглиэто в double с использованием только SSE2?

Это двойная версия, которую я хотел бы преобразовать:

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

1 Ответ

0 голосов
/ 28 января 2019

Просто используйте эквивалент двойной точности (...pd...) вашего одинарной точности (...ps...):

__m128i n = _mm_cvtpd_epi32(z);

Согласно IntelРуководство по встроенным функциям, это встроенное свойство действительно доступно для 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
...