Skip to content

Commit 8d19bd3

Browse files
committed
More numeric stability
1 parent abb2c63 commit 8d19bd3

2 files changed

Lines changed: 23 additions & 19 deletions

File tree

modules/yup_simd/buffers/yup_ComplexVectorOperations.cpp

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,22 @@ void complexMultiply (const float* __restrict a, const float* __restrict b, floa
3030

3131
#if YUP_USE_AVX_INTRINSICS && YUP_USE_FMA_INTRINSICS
3232
constexpr int simdWidth = 4;
33+
const __m256 signs = _mm256_set_ps (1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f);
34+
3335
for (; i <= complexPairs - simdWidth; i += simdWidth)
3436
{
3537
const int idx = i * 2;
3638

37-
__m256 av = _mm256_loadu_ps (a + idx);
38-
__m256 bv = _mm256_loadu_ps (b + idx);
39-
40-
const __m256 aShuffled = _mm256_permute_ps (av, _MM_SHUFFLE (2, 3, 0, 1));
41-
const __m256 bShuffled = _mm256_permute_ps (bv, _MM_SHUFFLE (2, 3, 0, 1));
39+
const __m256 av = _mm256_loadu_ps (a + idx);
40+
const __m256 bv = _mm256_loadu_ps (b + idx);
4241

43-
__m256 realPart = _mm256_fmsub_ps (av, bv, _mm256_mul_ps (aShuffled, bShuffled));
44-
__m256 imagPart = _mm256_fmadd_ps (av, bShuffled, _mm256_mul_ps (aShuffled, bv));
42+
const __m256 aReal = _mm256_permute_ps (av, _MM_SHUFFLE (2, 2, 0, 0));
43+
const __m256 aImag = _mm256_permute_ps (av, _MM_SHUFFLE (3, 3, 1, 1));
44+
const __m256 bSwapped = _mm256_permute_ps (bv, _MM_SHUFFLE (2, 3, 0, 1));
45+
const __m256 realProducts = _mm256_mul_ps (aReal, bv);
46+
const __m256 imagProducts = _mm256_mul_ps (aImag, bSwapped);
4547

46-
__m256 interleaved = _mm256_blend_ps (realPart, imagPart, 0b10101010);
48+
__m256 interleaved = _mm256_fmadd_ps (imagProducts, signs, realProducts);
4749

4850
if (accumulate)
4951
interleaved = _mm256_add_ps (_mm256_loadu_ps (y + idx), interleaved);
@@ -53,20 +55,22 @@ void complexMultiply (const float* __restrict a, const float* __restrict b, floa
5355

5456
#elif YUP_USE_SSE_INTRINSICS
5557
constexpr int simdWidth = 2;
58+
const __m128 signs = _mm_set_ps (1.0f, -1.0f, 1.0f, -1.0f);
59+
5660
for (; i <= complexPairs - simdWidth; i += simdWidth)
5761
{
5862
const int idx = i * 2;
5963

60-
__m128 av = _mm_loadu_ps (a + idx);
61-
__m128 bv = _mm_loadu_ps (b + idx);
62-
63-
const __m128 aShuffled = _mm_shuffle_ps (av, av, _MM_SHUFFLE (2, 3, 0, 1));
64-
const __m128 bShuffled = _mm_shuffle_ps (bv, bv, _MM_SHUFFLE (2, 3, 0, 1));
64+
const __m128 av = _mm_loadu_ps (a + idx);
65+
const __m128 bv = _mm_loadu_ps (b + idx);
6566

66-
__m128 realPart = _mm_sub_ps (_mm_mul_ps (av, bv), _mm_mul_ps (aShuffled, bShuffled));
67-
__m128 imagPart = _mm_add_ps (_mm_mul_ps (av, bShuffled), _mm_mul_ps (aShuffled, bv));
67+
const __m128 aReal = _mm_shuffle_ps (av, av, _MM_SHUFFLE (2, 2, 0, 0));
68+
const __m128 aImag = _mm_shuffle_ps (av, av, _MM_SHUFFLE (3, 3, 1, 1));
69+
const __m128 bSwapped = _mm_shuffle_ps (bv, bv, _MM_SHUFFLE (2, 3, 0, 1));
70+
const __m128 realProducts = _mm_mul_ps (aReal, bv);
71+
const __m128 imagProducts = _mm_mul_ps (aImag, bSwapped);
6872

69-
__m128 interleaved = _mm_unpacklo_ps (realPart, imagPart);
73+
__m128 interleaved = _mm_add_ps (realProducts, _mm_mul_ps (imagProducts, signs));
7074

7175
if (accumulate)
7276
interleaved = _mm_add_ps (_mm_loadu_ps (y + idx), interleaved);

tests/yup_dsp/yup_BiquadCascade.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -398,11 +398,11 @@ TEST_F (BiquadCascadeFilterTests, StabilityCheck)
398398
auto coeffs = FilterDesigner<double>::designRbjLowpass (5000.0, 50.0, sampleRate);
399399
cascadeFloat.setSectionCoefficients (0, coeffs);
400400

401-
// Process white noise-like signal
401+
// Process deterministic white noise-like signal
402402
std::vector<float> noiseInput (blockSize);
403-
WhiteNoise noise;
403+
WhiteNoise noise (12345);
404404
for (int i = 0; i < blockSize; ++i)
405-
noiseInput[i] = noise.getNextSample();
405+
noiseInput[i] = 0.1f * noise.getNextSample();
406406

407407
cascadeFloat.processBlock (noiseInput.data(), outputData.data(), blockSize);
408408

0 commit comments

Comments
 (0)