Быстрое двойное -> короткое преобразование с зажимом с использованием SSE? - PullRequest
2 голосов
/ 09 июня 2010

Есть ли быстрый способ приведения двойных значений к шортам (16 битов со знаком), сейчас я делаю что-то вроде этого:

double  dval = <sum junk>
int16_t sval;
if (val > int16_max) { 
   sval = int16_max;
} else if (val < int16_min) {
   sval = int16_min;
} else 
   sval = (int16_t)val;

Я подозреваю, что есть быстрый способ сделать это с использованием SSE, который будет значительно более эффективным.

1 Ответ

4 голосов
/ 09 июня 2010

Найдите minsd, maxsd и cvtsd2si, или, если вы хотите сделать 2 параллельно, используйте minpd, maxpd и cvtpd2dq.

Единственный реальный бонус использования первого метода - это сохранение веток.Сгенерированный код SSE2 будет почти в два раза быстрее с использованием кода, скомпилированного в SSE2, в любом случае ... Настоящая победа заключается в том, что вы выполняете 2 из них одновременно.

Редактировать: Если вы хотите это сделатьиспользуя встроенные функции Visual Studio, я считаю, что код будет выглядеть следующим образом:

 __m128d sseDbl = _mm_set_sd( dbl );
 sseDbl         = _mm_min_sd( dbl, _mm_set_sd( 32767.0 ) );
 sseDbl         = _mm_max_sd( dbl, _mm_set_sd( -32768.0 ) );
 short shrtVal  = (short)_mm_cvtsd_si32( sseDbl );

И работа выполнена.Выполнение этого с использованием ассемблера также очень похоже, но приведенное выше определенно даст вам лучшую производительность с Visual Studio.

...