потолок/пол в sse simd

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

В настоящее время я использую код, аналогичный следующему (я использую встроенные функции 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

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


person Community    schedule 11.03.2011    source источник


Ответы (1)


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

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, чтобы обнаружить значения, выходящие за пределы допустимого диапазона.

person Jeremiah Willcock    schedule 11.03.2011