Closed Bug 1849806 Opened 1 year ago Closed 1 year ago

Reduce number of exp2 calls for detune effect calculations

Categories

(Core :: Web Audio, enhancement)

enhancement

Tracking

()

RESOLVED FIXED
118 Branch
Tracking Status
firefox118 --- fixed

People

(Reporter: karlt, Assigned: karlt)

References

Details

Attachments

(4 files)

Bug 1358149 comment 55 indicates that transcendental function evaluation is having a significant effect on performance. exp2() is a commonly called such function. Skipping the calls in common unnecessary cases can improve performance.

When recomputing the AudioBufferSourceNode output rate only when necessary, the geometric mean results improve by ~1%, as many of the webaudio benchmarks use AudioBufferSourceNode. Granular synthesis speed improves by 5% or so.

OscillatorNode already caches its computed frequency so only "Periodic Wave with Automation" and "Substractive synth" benchmarks are repeatedly calculating the detune effect because the frequency is automated. Caching the detune calculation improves speeds by 11-24% and 7-13%. The linked results are the combined effect of skipping ABSN playback rate calculations and OscillatorNode detune calculations, but "Periodic Wave with Automation" and "Substractive synth" do not use ABSN.

I haven't cached the result of the detune calculation in AudioBufferSourceNode when the playbackRate is changing. AudioBufferSourceNode would recalculate detune a maximum of once per render block, and I expect resampler re-initialization time to swamp detune effect calculation time.

I considered switching from exp2 to the lower precision exp2f in OscillatorNode, but this function can amplify rounding error. Consider an input a x where x is close to 1 but contains rounding error. For f(x) = 2^(ax), f'(x)/f(x) = a ln 2. Rounding error is attenuated when |detune/1200| < 1 / ln 2. i.e. |detune| ⪅ 1700, so exp2f would be fine for typical moderate values. For a large detune of 10 octaves, however, error is amplified by 10 ln 2 ≅ 7. i.e. almost 3 of the 24 bits of precision would be lost.

to avoid the exp2f() call, which was showing up in benchmarks.

Depends on D186688

Pushed by ktomlinson@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/b5371614cd5a cache detune arithmetic in OscillatorNode r=padenot
Pushed by ktomlinson@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/c668c58af537 remove an unnecessary division in phase increment calculation r=padenot
Pushed by ktomlinson@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/9a1dfe1dd89a recalculate phase increment only when frequency changes r=padenot
Status: ASSIGNED → RESOLVED
Closed: 1 year ago
Resolution: --- → FIXED
Target Milestone: --- → 118 Branch
Pushed by ktomlinson@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/27b0c1032942 recompute buffer source output rate only when necessary r=padenot

Something surprising in the OscillatorNode automation benchmark measurements was that they showed a noticeable difference from removing the unnecessary division. Numbers on 64-bit WINNT were

Base New Delta Confidence Total Runs
Periodic Wave with Automation 182.14 ± 1.12 > 176.71 ± 0.78 -2.98% 5.84 (high) 7 / 7
Substractive synth 288.71 ± 0.56 > 283.71 ± 0.63 -1.73% 5.49 (high) 7 / 7

Numbers of other platforms were similar with some variability.

So I experimented with removing another division, but didn't get further improvements.

You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: