SIMD/Uses/Conversion

< SIMD
Revision as of 20:07, 12 April 2014 by Maikmerten (talk | contribs) (SSE2 conversion options)

In multimedia coding, converting data types is not uncommon. For instance, in JPEG and MPEG the reference DCT is operating on double precision intermediates, but the resulting coefficients are stored as integer values. Converting floating point values to integer types looks innocent enough written in C:

int i;
double d = 0.99;
i = (int) d;

The resulting value for a is 0, as casting in C will truncate any positions after the decimal point -- no rounding will occur. The same is true for JavaScript. (In JavaScript, the bitwise operators such as | will trigger an integer conversion.)

To get proper rounding, following approach is often employed:

if(d > 0) {
   i = (int) d + 0.5;
} else {
   i = (int) d - 0.5;
}

often written in a more compact fashion using a ternary operator:

i = (int) d > 0 ? (d + 0.5) : (d - 0.5);

This works, but is not particularly fast: For every value a conditional statement is executed, making the code very "branchy", which is generally disliked by pipelined processor designs. No matter what branch is taken, preceding the type conversion there's an additional arithmetic operation to apply the fitting offset.

SIMD instruction sets like SSE2 have specialized data conversion operations -- including, e.g., conversion of floating point values to integer values with rounding. In the case of SSE2, both scalar and vector values can be converted (i.e., a single value at a time or a vector of values). In the latter case, the conversion does not only avoid costly branches and additional arithmetic operations, but also gives several converted values with a single operation.