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
3030 }
3131 }
3232
33+void 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+
3354 void GeneralBilinearFastDownsampler_ref (uint8_t* pDst, const int32_t kiDstStride, const int32_t kiDstWidth,
3455 const int32_t kiDstHeight,
3556 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
162183 }
163184 }
164185
165−#define GENERATE_DyadicBilinearDownsampler_UT(func, ASM, CPUFLAGS) \
186+#define GENERATE_DyadicBilinearDownsampler_UT_with_ref(func, ASM, CPUFLAGS, ref_func) \
166187 TEST (DownSampleTest, func) { \
167188 if (ASM) {\
168189 int32_t iCpuCores = 0; \
@@ -190,7 +211,7 @@ TEST (DownSampleTest, func) { \ · 21 unmodified lines
190211 dst_c[j] = dst_a[j] = rand() % 256; \
191212 src_c[j] = src_a[j] = rand() % 256; \
192213 } \
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); \
194215 func (dst_a, dst_stride_a, src_a, src_stride_a, src_width_a, src_height_a); \
195216 for (int j = 0; j < (src_height_c >> 1); j++) { \
196217 for (int m = 0; m < (src_width_c >> 1); m++) { \
@@ -199,6 +220,11 @@ TEST (DownSampleTest, func) { \ · 2 unmodified lines
199220 } \
200221 }
201222
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+
202228 #define GENERATE_DyadicBilinearOneThirdDownsampler_UT(func, ASM, CPUFLAGS) \
203229 TEST (DownSampleTest, func) { \
204230 if (ASM) {\
@@ -328,11 +354,8 @@ GENERATE_DyadicBilinearDownsampler_UT (DyadicBilinearDownsamplerWidthx32_sse, 1, · 123 unmodified lines
328354 GENERATE_DyadicBilinearDownsampler_UT (DyadicBilinearDownsamplerWidthx16_sse, 1, WELS_CPU_SSE)
329355 GENERATE_DyadicBilinearDownsampler_UT (DyadicBilinearDownsamplerWidthx8_sse, 1, WELS_CPU_SSE)
330356
331−GENERATE_DyadicBilinearDownsampler_UT (DyadicBilinearDownsamplerWidthx32_ssse3, 1, WELS_CPU_SSSE3)
332−GENERATE_DyadicBilinearDownsampler_UT (DyadicBilinearDownsamplerWidthx16_ssse3, 1, WELS_CPU_SSSE3)
333−
334−GENERATE_DyadicBilinearDownsampler_UT (DyadicBilinearDownsamplerWidthx32_sse4, 1, WELS_CPU_SSE41)
335−GENERATE_DyadicBilinearDownsampler_UT (DyadicBilinearDownsamplerWidthx16_sse4, 1, WELS_CPU_SSE41)
357+GENERATE_DyadicBilinearDownsampler2_UT (DyadicBilinearDownsamplerWidthx32_ssse3, 1, WELS_CPU_SSSE3)
358+GENERATE_DyadicBilinearDownsampler2_UT (DyadicBilinearDownsamplerWidthx16_ssse3, 1, WELS_CPU_SSSE3)
336359
337360 GENERATE_DyadicBilinearOneThirdDownsampler_UT (DyadicBilinearOneThirdDownsampler_ssse3, 1, WELS_CPU_SSSE3)
338361 GENERATE_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