History

[Processing/x86] DyadicBilinearDownsample optimizations

Average vertically before horizontally; horizontal averaging is more worksome. Doing the vertical averaging first reduces the number of horizontal averages by half. Use pmaddubsw and pavgw to do the horizontal averaging for a slight performance improvement. Minor tweaks. Improve the SSSE3 dyadic downsample routines and drop the SSE4 routines. The non-temporal loads used in the SSE4 routines do nothing for cache- backed memory AFAIK. Adjust tests because averaging vertically first gives slightly different output. ~2.39x speedup for the widthx32 routine on Haswell when not memory-bound. ~2.20x speedup for the widthx16 routine on Haswell when not memory-bound. Note that the widthx16 routine can be unrolled for further speedup.

Sindre Aamås committed 10 years ago

Commit 8a0af4a1 parent 7cbb75e7 files · +95 −372Browse files

Showing the changes to test/processing/ProcessUT_DownSample.cpp (1 of 7 files). Show all

Unified · Split

test/processing/ProcessUT_DownSample.cpp+30−7
@@ -30,6 +30,27 @@ void DyadicBilinearDownsampler_ref (uint8_t* pDst, const int32_t kiDstStride, · 29 unmodified lines
30 }30 }
31}31}
32 32
33void DyadicBilinearDownsampler2_ref (uint8_t* pDst, const int32_t kiDstStride,
34 const uint8_t* pSrc, const int32_t kiSrcStride,
35 const int32_t kiSrcWidth, const int32_t kiSrcHeight) {
36 uint8_t* pDstLine = pDst;
37 const uint8_t* pSrcLine1 = pSrc;
38 const uint8_t* pSrcLine2 = pSrc + kiSrcStride;
39 const int32_t kiDstWidth = kiSrcWidth >> 1;
40 const int32_t kiDstHeight = kiSrcHeight >> 1;
41
42 for (int32_t j = 0; j < kiDstHeight; j++) {
43 for (int32_t i = 0; i < kiDstWidth; i++) {
44 const int32_t kiTempCol1 = (pSrcLine1[2 * i + 0] + pSrcLine2[2 * i + 0] + 1) >> 1;
45 const int32_t kiTempCol2 = (pSrcLine1[2 * i + 1] + pSrcLine2[2 * i + 1] + 1) >> 1;
46 pDstLine[i] = (uint8_t) ((kiTempCol1 + kiTempCol2 + 1) >> 1);
47 }
48 pDstLine += kiDstStride;
49 pSrcLine1 += 2 * kiSrcStride;
50 pSrcLine2 += 2 * kiSrcStride;
51 }
52}
53
33void GeneralBilinearFastDownsampler_ref (uint8_t* pDst, const int32_t kiDstStride, const int32_t kiDstWidth,54void GeneralBilinearFastDownsampler_ref (uint8_t* pDst, const int32_t kiDstStride, const int32_t kiDstWidth,
34 const int32_t kiDstHeight,55 const int32_t kiDstHeight,
35 uint8_t* pSrc, const int32_t kiSrcStride, const int32_t kiSrcWidth, const int32_t kiSrcHeight) {56 uint8_t* pSrc, const int32_t kiSrcStride, const int32_t kiSrcWidth, const int32_t kiSrcHeight) {
@@ -162,7 +183,7 @@ void GeneralBilinearAccurateDownsampler_ref (uint8_t* pDst, const int32_t kiDstS · 126 unmodified lines
162 }183 }
163}184}
164 185
165#define GENERATE_DyadicBilinearDownsampler_UT(func, ASM, CPUFLAGS) \186#define GENERATE_DyadicBilinearDownsampler_UT_with_ref(func, ASM, CPUFLAGS, ref_func) \
166TEST (DownSampleTest, func) { \187TEST (DownSampleTest, func) { \
167 if (ASM) {\188 if (ASM) {\
168 int32_t iCpuCores = 0; \189 int32_t iCpuCores = 0; \
@@ -190,7 +211,7 @@ TEST (DownSampleTest, func) { \ · 21 unmodified lines
190 dst_c[j] = dst_a[j] = rand() % 256; \211 dst_c[j] = dst_a[j] = rand() % 256; \
191 src_c[j] = src_a[j] = rand() % 256; \212 src_c[j] = src_a[j] = rand() % 256; \
192 } \213 } \
193 DyadicBilinearDownsampler_ref (dst_c, dst_stride_c, src_c, src_stride_c, src_width_c, src_height_c); \214 ref_func (dst_c, dst_stride_c, src_c, src_stride_c, src_width_c, src_height_c); \
194 func (dst_a, dst_stride_a, src_a, src_stride_a, src_width_a, src_height_a); \215 func (dst_a, dst_stride_a, src_a, src_stride_a, src_width_a, src_height_a); \
195 for (int j = 0; j < (src_height_c >> 1); j++) { \216 for (int j = 0; j < (src_height_c >> 1); j++) { \
196 for (int m = 0; m < (src_width_c >> 1); m++) { \217 for (int m = 0; m < (src_width_c >> 1); m++) { \
@@ -199,6 +220,11 @@ TEST (DownSampleTest, func) { \ · 2 unmodified lines
199 } \220 } \
200}221}
201 222
223#define GENERATE_DyadicBilinearDownsampler_UT(func, ASM, CPUFLAGS) \
224 GENERATE_DyadicBilinearDownsampler_UT_with_ref(func, ASM, CPUFLAGS, DyadicBilinearDownsampler_ref)
225#define GENERATE_DyadicBilinearDownsampler2_UT(func, ASM, CPUFLAGS) \
226 GENERATE_DyadicBilinearDownsampler_UT_with_ref(func, ASM, CPUFLAGS, DyadicBilinearDownsampler2_ref)
227
202#define GENERATE_DyadicBilinearOneThirdDownsampler_UT(func, ASM, CPUFLAGS) \228#define GENERATE_DyadicBilinearOneThirdDownsampler_UT(func, ASM, CPUFLAGS) \
203TEST (DownSampleTest, func) { \229TEST (DownSampleTest, func) { \
204 if (ASM) {\230 if (ASM) {\
@@ -328,11 +354,8 @@ GENERATE_DyadicBilinearDownsampler_UT (DyadicBilinearDownsamplerWidthx32_sse, 1, · 123 unmodified lines
328GENERATE_DyadicBilinearDownsampler_UT (DyadicBilinearDownsamplerWidthx16_sse, 1, WELS_CPU_SSE)354GENERATE_DyadicBilinearDownsampler_UT (DyadicBilinearDownsamplerWidthx16_sse, 1, WELS_CPU_SSE)
329GENERATE_DyadicBilinearDownsampler_UT (DyadicBilinearDownsamplerWidthx8_sse, 1, WELS_CPU_SSE)355GENERATE_DyadicBilinearDownsampler_UT (DyadicBilinearDownsamplerWidthx8_sse, 1, WELS_CPU_SSE)
330 356
331GENERATE_DyadicBilinearDownsampler_UT (DyadicBilinearDownsamplerWidthx32_ssse3, 1, WELS_CPU_SSSE3)357GENERATE_DyadicBilinearDownsampler2_UT (DyadicBilinearDownsamplerWidthx32_ssse3, 1, WELS_CPU_SSSE3)
332GENERATE_DyadicBilinearDownsampler_UT (DyadicBilinearDownsamplerWidthx16_ssse3, 1, WELS_CPU_SSSE3)358GENERATE_DyadicBilinearDownsampler2_UT (DyadicBilinearDownsamplerWidthx16_ssse3, 1, WELS_CPU_SSSE3)
333
334GENERATE_DyadicBilinearDownsampler_UT (DyadicBilinearDownsamplerWidthx32_sse4, 1, WELS_CPU_SSE41)
335GENERATE_DyadicBilinearDownsampler_UT (DyadicBilinearDownsamplerWidthx16_sse4, 1, WELS_CPU_SSE41)
336 359
337GENERATE_DyadicBilinearOneThirdDownsampler_UT (DyadicBilinearOneThirdDownsampler_ssse3, 1, WELS_CPU_SSSE3)360GENERATE_DyadicBilinearOneThirdDownsampler_UT (DyadicBilinearOneThirdDownsampler_ssse3, 1, WELS_CPU_SSSE3)
338GENERATE_DyadicBilinearOneThirdDownsampler_UT (DyadicBilinearOneThirdDownsampler_sse4, 1, WELS_CPU_SSE41)361GENERATE_DyadicBilinearOneThirdDownsampler_UT (DyadicBilinearOneThirdDownsampler_sse4, 1, WELS_CPU_SSE41)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t