DUBLE DUPLO RÁPIDO -> Conversão curta com aperto usando SSE?
Pergunta
Existe uma maneira rápida de lançar valores duplos em shorts (16 bits assinados), atualmente estou fazendo algo assim:
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;
Suspeito que haja uma maneira rápida de fazer isso usando SSE que será significativamente mais eficiente.
Solução
Procure MINSD, MAXSD e CVTSD2SI, ou se você deseja fazer 2 em paralelo, use o MINPD, MAXPD e CVTPD2DQ.
O único bônus real de usar o primeiro método é que você salva as ramificações. O código SSE2 gerado será, praticamente, tão rápido quanto o dobro usando o código compilado para o SSE2 de qualquer maneira ... A verdadeira vitória vem de fazer 2 deles por vez.
EDIT: Se você quisesse fazer isso usando o Visual Studio Intrinsics, acredito que o código seria o seguinte:
__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 );
E trabalho feito. Fazer isso usando o Assembler também é bem semelhante, mas o acima definitivamente lhe daria melhor desempenho no Visual Studio.