Remove per-macroblock allocations from the lossy WebP encoder - #3192
Merged
Merged
Conversation
The VP8 mode pickers created new Vp8ModeScore and Vp8Residual objects for every macroblock, and RecordResiduals created a residual per macroblock in every stat pass. Hold the scratch accumulators on Vp8EncIterator, create the stat-pass residual once per pass, and reuse them.
Macroblock analysis created a Vp8Histogram object for every candidate mode and a two-element array for every 4x4 block. The type only holds two ints, so make it a value type, keep the two alternating histograms on the stack, and merge by reference.
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.
Prerequisites
Description
The VP8 encoder allocated on every macroblock. The three mode pickers in
QuantEnccreated newVp8ModeScoreandVp8Residualobjects,RecordResidualscreated a residual per macroblock in every stat pass, and macroblock analysis created aVp8Histogramobject per candidate mode. The GC collected all of it, so this was churn, not a leak, but it showed up as gigabytes of allocation in profiles of large batch jobs (see #3191).Changes:
Vp8EncIteratornow owns threeVp8ModeScorescratch accumulators and oneVp8Residual.QuantEncreuses them. The intra16 picker hands the rejected accumulator back to the iterator, so the existing reference swap still avoids a copy.OneStatPasscreates one residual per pass and passes it toRecordResiduals.Vp8Histogramis now a struct. The two alternating histograms inMbAnalyzeBestIntra4Modelive on the stack, andMergetakes the accumulator by reference.Output is unchanged. All 435 WebP tests pass.
EncodeWebplossy benchmark,Png/Bike.png, .NET 10: