Optimize Opus decoding for ARM64 - #239
Merged
Merged
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #239 +/- ##
==========================================
- Coverage 93.37% 93.34% -0.03%
==========================================
Files 58 61 +3
Lines 10710 10928 +218
==========================================
+ Hits 10000 10201 +201
- Misses 501 518 +17
Partials 209 209
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Specialize entropy decoding, SILK synthesis, CELT deemphasis, and fixed-point resampling. Use an ARM64 NEON kernel for the eight-tap FIR interpolator, with portable fallbacks. Document the arithmetic constraints and prediction history boundaries. Validation: all 120 official RFC conformance cases pass on Go 1.27.1 ARM64 with an unchanged quality matrix. Build selection retains NEON on ARM64 and the scalar fallback on other architectures; the Linux amd64 build passes.
zshang-oai
force-pushed
the
codex/opus-decoder-perf-20260901
branch
from
September 2, 2026 21:53
60d2e20 to
7d06453
Compare
zshang-oai
marked this pull request as ready for review
September 2, 2026 21:55
JoTurk
approved these changes
Sep 3, 2026
JoTurk
left a comment
Member
There was a problem hiding this comment.
last time I read ARM64 assembly or NEON SIMD I was still in uni years ago .. so I can't really review this I just hope it's correct and doesn't have bugs. I tested it yesterday and it seem able to compile and run.
This was referenced Sep 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Reduce decoder CPU time with portable specializations and an ARM64 NEON resampling kernel. On an Apple M4 Max, complete RFC stream replays with 24 kHz mono
DecodeToInt16output take 18.5–27.0% less time than the base revision.Implementation
arm64 && go1.27 && !purego; other builds use the scalar implementation. The shared PCM quantizer is unchanged.LTP correctness
Frame index zero separates saved history from the current frame. Rewhitening an output at
ireads[i-dLPC, i], so only0 <= i < dLPCneeds mixed history access. Five-tap pitch prediction reads[i-lag-2, i-lag+2], so onlylag-2 <= i < lag+2needs mixed access: at most four output samples.For a contiguous output span
[A, B), the pitch helper receives source[A-lag-2, B-lag+2). Its local tapsource[t+4-k]maps exactly to the original indexA+t-lag+2-k. Rewhitening uses the correspondingdLPCpreceding samples. The helpers preserve tap order, clamp-before-gain scaling, and ascending sample writes. Source and destination may overlap during pitch prediction, so each result is stored before the next output reads its history. The existing gain-ratio adjustment and frame-history handoff are preserved.Measurements
Apple M4 Max, Go 1.27.0, 24 kHz mono
DecodeToInt16; values are median microseconds per packet. Each implementation runs five rounds of 60 complete-stream replays, with rotated execution order, a fresh decoder per replay, and warm-up outside the timer. Reference libopus is the optimized Homebrew 1.6.1 build; its decoding loop runs in C without per-packet cgo calls.1e54f79Timings were collected before comment cleanup and equivalent loop rewrites for lint; the final cleanup has not been retimed. These are complete conformance-stream measurements on this host. The reference integer API uses soft clipping while Pion's integer API hard-clips. Ratios remain 1.39–1.63 times libopus; results do not establish performance on other ARM64 CPUs.
Validation
TestRFC6716Conformance: 120/120 passed, covering all 12 streams, five sample rates, and mono/stereo. Latest ARM64 run after the lint fixes: Go 1.27.1, 73.189 s, no skips or failures, unchanged quality matrix.puregopath. NEON and portable output hashes matched for all 120 cases in the retained implementation.git diff --checkis clean.With the repository's RFC reference source and test vectors prepared: