From 7492a7ff46a75b5d8e10ae11d4ad50429cf945ce Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Sat, 10 Nov 2012 04:44:30 -0800 Subject: more optimizations... calculate the offsets from the phase differently, this happens to reduce the register pressure in the main loop, which in turns allows the compiler to generate much better code (doesn't need to spill a lot of stuff on the stack). this gives another 15% performance increase Change-Id: I2ce3479dd48b9e6941adb80e6d443d6e14d64d96 --- services/audioflinger/AudioResamplerSinc.cpp | 31 ++++++++++++++++------------ 1 file changed, 18 insertions(+), 13 deletions(-) (limited to 'services/audioflinger/AudioResamplerSinc.cpp') diff --git a/services/audioflinger/AudioResamplerSinc.cpp b/services/audioflinger/AudioResamplerSinc.cpp index 952abb4..d68b839 100644 --- a/services/audioflinger/AudioResamplerSinc.cpp +++ b/services/audioflinger/AudioResamplerSinc.cpp @@ -637,17 +637,20 @@ template void AudioResamplerSinc::filterCoefficient( int32_t* out, uint32_t phase, const int16_t *samples, uint32_t vRL) { + // NOTE: be very careful when modifying the code here. register + // pressure is very high and a small change might cause the compiler + // to generate far less efficient code. + // Always sanity check the result with objdump or test-resample. + // compute the index of the coefficient on the positive side and // negative side const Constants& c(*mConstants); + const int32_t ONE = c.cMask | c.pMask; uint32_t indexP = ( phase & c.cMask) >> c.cShift; - uint32_t indexN = (-phase & c.cMask) >> c.cShift; uint32_t lerpP = ( phase & c.pMask) >> c.pShift; - uint32_t lerpN = (-phase & c.pMask) >> c.pShift; - if ((indexP == 0) && (lerpP == 0)) { - indexN = c.cMask >> c.cShift; - lerpN = c.pMask >> c.pShift; - } + uint32_t indexN = ((ONE-phase) & c.cMask) >> c.cShift; + uint32_t lerpN = ((ONE-phase) & c.pMask) >> c.pShift; + const size_t offset = c.halfNumCoefs; indexP *= offset; indexN *= offset; @@ -677,7 +680,8 @@ void AudioResamplerSinc::filterCoefficient( asm ( "vmov.32 d2[0], %[lerpP] \n" // load the positive phase "vmov.32 d2[1], %[lerpN] \n" // load the negative phase - "veor q0, q0 \n" // result, initialize to 0 + "veor q0, q0, q0 \n" // result, initialize to 0 + "vshl.s32 d2, d2, #16 \n" // convert to 32 bits "1: \n" "vld1.16 { d4}, [%[sP]] \n" // load 4 16-bits stereo samples @@ -727,8 +731,8 @@ void AudioResamplerSinc::filterCoefficient( [coefsN1] "+r" (coefsN1), [sP] "+r" (sP), [sN] "+r" (sN) - : [lerpP] "r" (lerpP<<16), - [lerpN] "r" (lerpN<<16), + : [lerpP] "r" (lerpP), + [lerpN] "r" (lerpN), [vLR] "r" (mVolumeSIMD) : "cc", "memory", "q0", "q1", "q2", "q3", @@ -742,8 +746,9 @@ void AudioResamplerSinc::filterCoefficient( asm ( "vmov.32 d2[0], %[lerpP] \n" // load the positive phase "vmov.32 d2[1], %[lerpN] \n" // load the negative phase - "veor q0, q0 \n" // result, initialize to 0 - "veor q4, q4 \n" // result, initialize to 0 + "veor q0, q0, q0 \n" // result, initialize to 0 + "veor q4, q4, q4 \n" // result, initialize to 0 + "vshl.s32 d2, d2, #16 \n" // convert to 32 bits "1: \n" "vld2.16 {d4,d5}, [%[sP]] \n" // load 4 16-bits stereo samples @@ -802,8 +807,8 @@ void AudioResamplerSinc::filterCoefficient( [coefsN1] "+r" (coefsN1), [sP] "+r" (sP), [sN] "+r" (sN) - : [lerpP] "r" (lerpP<<16), - [lerpN] "r" (lerpN<<16), + : [lerpP] "r" (lerpP), + [lerpN] "r" (lerpN), [vLR] "r" (mVolumeSIMD) : "cc", "memory", "q0", "q1", "q2", "q3", "q4", -- cgit v1.1