Programming
optimization sse average simd
Updated Fri, 16 Sep 2022 09:43:24 GMT

Why do SSE integer averaging instructions (PAVGB/PAVGW) add 1 to temporary sum before calculating final result?


I have been working on SSE optimization for a video processing algorithm recently. I need to write the exactly same algorithm in C code to cross-check correctness of the algorithm. I forgot about this fact several time, that makes results of the two implementations become different.

I can modify the C implementation to make them match since this difference doesn't matter. But why these instructions are designed like this? Is there any mathematical reason behind it?

The Intel Instructions Reference only mentions this behavior and don't explain why. I also tried googling, but couldn't find anything about it.

UPDATE:

Thanks to Paul's answer. I didn't realize that is rounding/truncation problem. But since both operands are integer, the only fraction will be 0.5, and it has 2 "nearest integer". AFAIK there are several rounding methods for this situation. Why the instructions use rounding up specifically? Do most related applications need rounding up?




Solution

It's to give correct rounding, i.e. round to nearest rather than truncation. In general when you divide by N with integer values you need to do this to get correct rounding:

y = (x + N / 2) / N;

If you just do:

y = x / N;

then you will get a truncated (round to zero) result.

Round to nearest is generally preferred for image processing and DSP type applications.