diff options
| author | Logan Stromberg <loganstromberg@gmail.com> | 2023-02-21 02:44:57 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-02-21 11:44:57 +0100 |
| commit | edfd4d70c0f38d41c6ebb31508127b14727017bd (patch) | |
| tree | cf379010089a72cf1b33387e4ce664f51c8557d1 /Ryujinx.Audio/Renderer/Dsp/UpsamplerHelper.cs | |
| parent | fc43aecbbd37a83ebd03f8cfe8fbc033ce2bda7d (diff) | |
Use SIMD acceleration for audio upsampler (#4410)
* Use SIMD acceleration for audio upsampler filter kernel for a moderate speedup
* Address formatting. Implement AVX2 fast path for high quality resampling in ResamplerHelper
* now really, are we really getting the benefit of inlining 50+ line methods?
* adding unit tests for resampler + upsampler. The upsampler ones fail for some reason
* Fixing upsampler test. Apparently this algo only works at specific ratios
---------
Co-authored-by: Logan Stromberg <lostromb@microsoft.com>
Diffstat (limited to 'Ryujinx.Audio/Renderer/Dsp/UpsamplerHelper.cs')
| -rw-r--r-- | Ryujinx.Audio/Renderer/Dsp/UpsamplerHelper.cs | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/Ryujinx.Audio/Renderer/Dsp/UpsamplerHelper.cs b/Ryujinx.Audio/Renderer/Dsp/UpsamplerHelper.cs index 847acec2..6cdab5a7 100644 --- a/Ryujinx.Audio/Renderer/Dsp/UpsamplerHelper.cs +++ b/Ryujinx.Audio/Renderer/Dsp/UpsamplerHelper.cs @@ -2,6 +2,7 @@ using Ryujinx.Audio.Renderer.Server.Upsampler; using Ryujinx.Common.Memory; using System; using System.Diagnostics; +using System.Numerics; using System.Runtime.CompilerServices; namespace Ryujinx.Audio.Renderer.Dsp @@ -70,16 +71,32 @@ namespace Ryujinx.Audio.Renderer.Dsp return; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] float DoFilterBank(ref UpsamplerBufferState state, in Array20<float> bank) { float result = 0.0f; Debug.Assert(state.History.Length == HistoryLength); Debug.Assert(bank.Length == FilterBankLength); - for (int j = 0; j < FilterBankLength; j++) + + int curIdx = 0; + if (Vector.IsHardwareAccelerated) + { + // Do SIMD-accelerated block operations where possible. + // Only about a 2x speedup since filter bank length is short + int stopIdx = FilterBankLength - (FilterBankLength % Vector<float>.Count); + while (curIdx < stopIdx) + { + result += Vector.Dot( + new Vector<float>(bank.AsSpan().Slice(curIdx, Vector<float>.Count)), + new Vector<float>(state.History.AsSpan().Slice(curIdx, Vector<float>.Count))); + curIdx += Vector<float>.Count; + } + } + + while (curIdx < FilterBankLength) { - result += bank[j] * state.History[j]; + result += bank[curIdx] * state.History[curIdx]; + curIdx++; } return result; |
