потолок / пол в ссе симд - PullRequest
0 голосов
/ 11 марта 2011

Может кто-нибудь предложить быстрый способ вычисления float floor / ceil с использованием pre-SSE4.1 SIMD? Мне нужно правильно обрабатывать все угловые случаи, например, когда у меня есть float значение, которое не может быть представлено 32-битным int.

В настоящее время я использую аналогичный следующий код (я использую встроенные функции C, для ясности преобразованные в asm):

;make many copies of the data
movaps       xmm0,   [float_value]
movaps       xmm1,   xmm0
movaps       xmm2,   xmm0

;check if the value is not too large in magnitude
andps        xmm1,   [exp_mask]
pcmpgtd      xmm1,   [max_exp]

;calculate the floor()
cvttps2dq    xmm3,   xmm2
psrld        xmm2,   31
psubd        xmm3,   xmm2
cvtsq2ps     xmm2,   xmm3

;combine the results
andps        xmm0,   xmm1
andnps       xmm1,   xmm2
orps         xmm0,   xmm1

Есть ли более эффективный способ проверить, не слишком ли велико значение с плавающей запятой для 32-битного типа int?

1 Ответ

0 голосов
/ 11 марта 2011

Вот некоторый псевдокод для одного элемента, который должен быть непосредственно преобразован в векторные инструкции:

float f;
int i = (int)f; /* 0x80000000 if out of range (as from cvtps2dq) */
if (i == 0x80000000)
    return f;
else
    return (float)i;

Вы бы использовали режим округления для приведения к int во второй строке.Вы также можете проверить флаг IE в MXCSR, чтобы обнаружить значения вне диапазона.

...