sse2: faster bilinear interpolation (get rid of XOR instruction)
authorSiarhei Siamashka <siarhei.siamashka@gmail.com>
Mon, 28 Jan 2013 05:00:12 +0000 (07:00 +0200)
committerSiarhei Siamashka <siarhei.siamashka@gmail.com>
Sun, 28 Apr 2013 20:22:41 +0000 (23:22 +0300)
commitd768558ce195caa208262866f9262b29efff22dc
tree8f07c4166294b472d4b6f7157aab35baac03a9f9
parent59109f32930a0c163628f8087cbb0a15b19cb96b
sse2: faster bilinear interpolation (get rid of XOR instruction)

The old code was calculating horizontal weights for right pixels
in the following way (for simplicity assume 8-bit interpolation
precision):

  Start with "x = vx" and do increment "x += ux" after each pixel.
  In this case right pixel weight for interpolation can be calculated
  as "((x >> 8) ^ 0xFF) + 1", which is the same as "256 - (x >> 8)".

The new code instead:

  Starts with "x = -(vx + 1)", performs increment "x += -ux" after
  each pixel and calculates right weights as just "(x >> 8) + 1",
  eliminating the need for XOR operation in the inner loop.

So we have one instruction less on the critical path. Benchmarks
with "lowlevel-blt-bench -b src_8888_8888" using GCC 4.7.2 on
x86-64 system and default optimizations:

Intel Core i7 860 (2.8GHz):
    before: src_8888_8888 =  L1: 291.37  L2: 288.58  M:285.38
    after:  src_8888_8888 =  L1: 319.66  L2: 316.47  M:312.06

Intel Core2 T7300 (2GHz):
    before: src_8888_8888 =  L1: 121.95  L2: 118.38  M:118.52
    after:  src_8888_8888 =  L1: 128.82  L2: 125.12  M:124.88

Intel Atom N450 (1.67GHz):
    before: src_8888_8888 =  L1:  64.25  L2:  62.37  M: 61.80
    after:  src_8888_8888 =  L1:  64.23  L2:  62.37  M: 61.82

Inspired by the "sse2_bilinear_interpolation" function (single
pixel interpolation) from:
    http://lists.freedesktop.org/archives/pixman/2013-January/002575.html
pixman/pixman-sse2.c