ssse3: Add iterator for separable bilinear scaling
authorSøren Sandmann Pedersen <ssp@redhat.com>
Thu, 6 Jun 2013 20:15:39 +0000 (16:15 -0400)
committerSøren Sandmann Pedersen <ssp@redhat.com>
Mon, 16 Sep 2013 20:50:35 +0000 (16:50 -0400)
commit58a79dfe6d1fd62c2b66c69fdb64f6b8ecf61da5
tree23a3dcb9022c74946c19fccb4291a6eb56b2b0ea
parentf1792b32215d3b62084ee99fca5c448f1c7f8e1d
ssse3: Add iterator for separable bilinear scaling

This new iterator uses the SSSE3 instructions pmaddubsw and pabsw to
implement a fast iterator for bilinear scaling.

There is a graph here recording the per-pixel time for various
bilinear scaling algorithms as reported by scaling-bench:

    http://people.freedesktop.org/~sandmann/ssse3.v2/ssse3.v2.png

As the graph shows, this new iterator is clearly faster than the
existing C iterator, and when used with an SSE2 combiner, it is also
faster than the existing SSE2 fast paths for upscaling, though not for
downscaling.

Another graph:

    http://people.freedesktop.org/~sandmann/ssse3.v2/movdqu.png

shows the difference between writing to iter->buffer with movdqa,
movdqu on an aligned buffer, and movdqu on a deliberately unaligned
buffer. Since the differences are very small, the patch here avoids
using movdqa because imposing alignment restrictions on iter->buffer
may interfere with other optimizations, such as writing directly to
the destination image.

The data was measured with scaling-bench on a Sandy Bridge Core
i3-2350M @ 2.3GHz and is available in this directory:

    http://people.freedesktop.org/~sandmann/ssse3.v2/

where there is also a Gnumeric spreadsheet ssse3.v2.gnumeric
containing the per-pixel values and the graph.

V2:
- Use uintptr_t instead of unsigned long in the ALIGN macro
- Use _mm_storel_epi64 instead of _mm_cvtsi128_si64 as the latter form
  is not available on x86-32.
- Use _mm_storeu_si128() instead of _mm_store_si128() to avoid
  imposing alignment requirements on iter->buffer
pixman/pixman-ssse3.c