ref: 4906cea0276c17a089f3b7616a43511cbc5ff069
parent: b58259ab55674cb028898a0ac9e8fdd3cf1d4b39
author: Scott LaVarnway <slavarnway@google.com>
date: Fri Oct 20 01:21:15 EDT 2017
vpx: [x86] vpx_hadamard_16x16_avx2() improvements ~10% performance gain. Fixed the cosmetics noted in the previous commit. Change-Id: Iddf475f34d0d0a3e356b2143682aeabac459ed13
--- a/vpx_dsp/x86/avg_intrin_avx2.c
+++ b/vpx_dsp/x86/avg_intrin_avx2.c
@@ -106,47 +106,25 @@
hadamard_col8x2_avx2(src, 0);
hadamard_col8x2_avx2(src, 1);
- store_tran_low(_mm256_castsi256_si128(src[0]), coeff);
- coeff += 8;
- store_tran_low(_mm256_castsi256_si128(src[1]), coeff);
- coeff += 8;
- store_tran_low(_mm256_castsi256_si128(src[2]), coeff);
- coeff += 8;
- store_tran_low(_mm256_castsi256_si128(src[3]), coeff);
- coeff += 8;
- store_tran_low(_mm256_castsi256_si128(src[4]), coeff);
- coeff += 8;
- store_tran_low(_mm256_castsi256_si128(src[5]), coeff);
- coeff += 8;
- store_tran_low(_mm256_castsi256_si128(src[6]), coeff);
- coeff += 8;
- store_tran_low(_mm256_castsi256_si128(src[7]), coeff);
- coeff += 8;
+ // TODO(slavarnway): FIXME: For high bitdepths, it is unnecessary to
+ // mult/unpack/store here and load/pack the same memory in the next stage.
+ // Try using an intermediate buffer and store_tran_low() in the last stage.
+ store_tran_low(_mm256_permute2x128_si256(src[0], src[1], 0x20), coeff);
+ coeff += 16;
+ store_tran_low(_mm256_permute2x128_si256(src[2], src[3], 0x20), coeff);
+ coeff += 16;
+ store_tran_low(_mm256_permute2x128_si256(src[4], src[5], 0x20), coeff);
+ coeff += 16;
+ store_tran_low(_mm256_permute2x128_si256(src[6], src[7], 0x20), coeff);
+ coeff += 16;
- src[0] = _mm256_castsi128_si256(_mm256_extractf128_si256(src[0], 1));
- src[1] = _mm256_castsi128_si256(_mm256_extractf128_si256(src[1], 1));
- src[2] = _mm256_castsi128_si256(_mm256_extractf128_si256(src[2], 1));
- src[3] = _mm256_castsi128_si256(_mm256_extractf128_si256(src[3], 1));
- src[4] = _mm256_castsi128_si256(_mm256_extractf128_si256(src[4], 1));
- src[5] = _mm256_castsi128_si256(_mm256_extractf128_si256(src[5], 1));
- src[6] = _mm256_castsi128_si256(_mm256_extractf128_si256(src[6], 1));
- src[7] = _mm256_castsi128_si256(_mm256_extractf128_si256(src[7], 1));
-
- store_tran_low(_mm256_castsi256_si128(src[0]), coeff);
- coeff += 8;
- store_tran_low(_mm256_castsi256_si128(src[1]), coeff);
- coeff += 8;
- store_tran_low(_mm256_castsi256_si128(src[2]), coeff);
- coeff += 8;
- store_tran_low(_mm256_castsi256_si128(src[3]), coeff);
- coeff += 8;
- store_tran_low(_mm256_castsi256_si128(src[4]), coeff);
- coeff += 8;
- store_tran_low(_mm256_castsi256_si128(src[5]), coeff);
- coeff += 8;
- store_tran_low(_mm256_castsi256_si128(src[6]), coeff);
- coeff += 8;
- store_tran_low(_mm256_castsi256_si128(src[7]), coeff);
+ store_tran_low(_mm256_permute2x128_si256(src[0], src[1], 0x31), coeff);
+ coeff += 16;
+ store_tran_low(_mm256_permute2x128_si256(src[2], src[3], 0x31), coeff);
+ coeff += 16;
+ store_tran_low(_mm256_permute2x128_si256(src[4], src[5], 0x31), coeff);
+ coeff += 16;
+ store_tran_low(_mm256_permute2x128_si256(src[6], src[7], 0x31), coeff);
}
void vpx_hadamard_16x16_avx2(int16_t const *src_diff, int src_stride,
@@ -172,10 +150,10 @@
b2 = _mm256_srai_epi16(b2, 1);
b3 = _mm256_srai_epi16(b3, 1);
- store_tran_low_256(_mm256_add_epi16(b0, b2), coeff);
- store_tran_low_256(_mm256_add_epi16(b1, b3), coeff + 64);
- store_tran_low_256(_mm256_sub_epi16(b0, b2), coeff + 128);
- store_tran_low_256(_mm256_sub_epi16(b1, b3), coeff + 192);
+ store_tran_low(_mm256_add_epi16(b0, b2), coeff);
+ store_tran_low(_mm256_add_epi16(b1, b3), coeff + 64);
+ store_tran_low(_mm256_sub_epi16(b0, b2), coeff + 128);
+ store_tran_low(_mm256_sub_epi16(b1, b3), coeff + 192);
coeff += 16;
}
--- a/vpx_dsp/x86/bitdepth_conversion_avx2.h
+++ b/vpx_dsp/x86/bitdepth_conversion_avx2.h
@@ -27,33 +27,17 @@
#endif
}
-// Store 8 16 bit values. If the destination is 32 bits then sign extend the
-// values by multiplying by 1.
-static INLINE void store_tran_low(__m128i a, tran_low_t *b) {
+static INLINE void store_tran_low(__m256i a, tran_low_t *b) {
#if CONFIG_VP9_HIGHBITDEPTH
- const __m128i one = _mm_set1_epi16(1);
- const __m128i a_hi = _mm_mulhi_epi16(a, one);
- const __m128i a_lo = _mm_mullo_epi16(a, one);
- const __m128i a_1 = _mm_unpacklo_epi16(a_lo, a_hi);
- const __m128i a_2 = _mm_unpackhi_epi16(a_lo, a_hi);
- _mm_store_si128((__m128i *)(b), a_1);
- _mm_store_si128((__m128i *)(b + 4), a_2);
-#else
- _mm_store_si128((__m128i *)(b), a);
-#endif
-}
-
-static INLINE void store_tran_low_256(__m256i a, tran_low_t *b) {
-#if CONFIG_VP9_HIGHBITDEPTH
const __m256i one = _mm256_set1_epi16(1);
const __m256i a_hi = _mm256_mulhi_epi16(a, one);
const __m256i a_lo = _mm256_mullo_epi16(a, one);
const __m256i a_1 = _mm256_unpacklo_epi16(a_lo, a_hi);
const __m256i a_2 = _mm256_unpackhi_epi16(a_lo, a_hi);
- _mm256_storeu_si256((__m256i *)(b), a_1);
+ _mm256_storeu_si256((__m256i *)b, a_1);
_mm256_storeu_si256((__m256i *)(b + 8), a_2);
#else
- _mm256_storeu_si256((__m256i *)(b), a);
+ _mm256_storeu_si256((__m256i *)b, a);
#endif
}
#endif // VPX_DSP_X86_BITDEPTH_CONVERSION_AVX2_H_