tags:

views:

55

answers:

1

Is there a fast way to cast double values to shorts (16 bits signed), currently I'm doing something like this:

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;

I suspect there's a fast way to do this using SSE that will be significantly more efficient.

+4  A: 

Look up minsd, maxsd and cvtsd2si.

Or if you want to do 2 in parallel then minpd, maxpd and cvtpd2dq.

The only real bonus of using the first method is that you save the branches. The SSE2 code generated will be, pretty much, as fast as double using code compiled to SSE2 anyway ... The real win comes from doing 2 of them at a time.

Edit: If you wanted to do it using Visual Studio intrinsics then I believe the code would look like the following:

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

And job done. Doing it using assembler is pretty similar as well but the above would definitely give you better performance with Visual Studio.

Goz
google search turned up this thread: http://www.gamedev.net/community/forums/topic.asp?topic_id=256880
zdav
Updated using VS Intrinsics.
Goz
Excellent, thanks!
gct