Repository navigation
Conversation
Use AArch64-specific timing coefficients for HUF_selectDecoder(). The existing selector formula and all non-AArch64 behavior remain unchanged. Signed-off-by: Kevin Yang <kjy@fb.com>
| {{ 150,216}, { 381,119}}, /* Q == 2 : 12-18% */ | ||
| {{ 314,167}, { 349,102}}, /* Q == 3 : 18-25% */ | ||
| {{ 291,167}, { 448,103}}, /* Q == 4 : 25-32% */ | ||
| {{ 197,194}, { 644,107}}, /* Q == 5 : 32-38% */ | ||
| {{ 170,167}, { 296,102}}, /* Q == 6 : 38-44% */ | ||
| {{ 173,167}, { 339,103}}, /* Q == 7 : 44-50% */ | ||
| {{ 229,169}, { 539,108}}, /* Q == 8 : 50-56% */ | ||
| {{ 258,168}, { 631,103}}, /* Q == 9 : 56-62% */ | ||
| {{ 688,187}, {1712,122}}, /* Q ==10 : 62-69% */ | ||
| {{ 825,186}, {1965,136}}, /* Q ==11 : 69-75% */ | ||
| {{ 515,169}, {1327,180}}, /* Q ==12 : 75-81% */ | ||
| {{ 543,169}, { 862,199}}, /* Q ==13 : 81-87% */ | ||
| {{1377,185}, {1731,202}}, /* Q ==14 : 87-93% */ | ||
| {{1412,185}, {1695,202}}, /* Q ==15 : 93-99% */ |
There was a problem hiding this comment.
I see that Q=2,5,10,14,15 are unchanged from the x86 rows. Why is that?
There was a problem hiding this comment.
I fitted an intercept/slope for every Q bucket using some synthetic data by measuring X1 and X2 total time on that data. After this, I replayed the selector decisions on separate synthetic datasets as well as the data in https://github.com/terrelln/huffman-sample-files. I then retain a changed row if it changes at least one decision and reduced the measured total HUF cost.
For Q2, Q5, Q11, Q14, and Q15 the decision between X1 and X2 was the same for aarch64 fitted vs. status quo for all of the samples I ran. So for those, I kept the rows unchanged.
For Q10, the fitting procedure produced a Q10 row that overwhelmingly selected X2, but when I validated the row later against some workloads it regressed so I opted to keep that untouched.
Open to suggestions on the tuning methodology!
|
I'm measuring a slight performance regression on the silesia corpus when benchmarking on a Neoverse-V2 CPU: On an M4 chip, I see a slight increase in performance: |
Hmm, I was not able to reproduce this but let me run a few more times and look into this |
|
I'm going on vacation for October, so @Cyan4973 will have to take over the review |
Summary
Add AArch64-specific timing coefficients to
HUF_selectDecoder(). The decoderimplementations, selector formula, X2 cache-cost adjustment, and non-AArch64
table are unchanged.
X2 has a higher fixed table-construction cost, but can decode two symbols per
lookup when their combined code length fits in one entry. The break-even point
therefore depends on both the Huffman distribution and the target CPU. Native
measurements showed that the existing coefficients systematically select a
suboptimal decoder for some AArch64 inputs.
Calibration methodology
I benchmarked X1 and X2 independently on the same valid Huffman blocks,
measuring table construction, decoding, and their combined cost. The inputs
were deterministic synthetic symbol distributions designed to cover every
selector quantization bucket. For each distribution, the benchmark exercised
ten output sizes from 256 bytes through 128 KiB and recorded five timing
rounds.
The selector models each decoder as:
For each quantization bucket and decoder, I first took the median measurement
at each output size, then fitted the intercept and slope of that model. Three
disjoint deterministic seeds were used as separate fitting, gating, and
held-out datasets. A fitted row was retained only when it changed a selector
decision and did not increase measured combined cost on the gating dataset;
otherwise that row kept the existing coefficients.
The initial calibration used three separate 72-core Arm Neoverse V2 systems,
one for each dataset. I then repeated the full three-seed, ten-size, five-round
matrix on a 128-core Arm Neoverse V3AE system, pinned to one CPU, to test
whether one AArch64 table generalized across microarchitectures.
"Selector accuracy" is the fraction of samples for which the model chooses the
decoder with the lower measured combined cost. "Oracle regret" is the excess
cost relative to choosing the faster measured decoder independently for every
sample.
A table fitted specifically to the V3AE measurements reduced selected cost by
1.316%, only 0.021 percentage points more than the shared candidate. No
quantization bucket regressed on the V3AE held-out dataset.
The resulting changes are concentrated in two regions: X2 is selected at
smaller block sizes for compressible inputs in Q3-Q9, while X1 remains selected
for weakly compressible inputs in Q12-Q13. Rows without a validated
improvement retain the existing coefficients.
The calibration corpus is synthetic so it can exercise the complete selector
decision surface reproducibly; the results above measure the selector and HUF
table-build/decode work directly rather than an end-to-end application
workload.
Testing
make checkon the currentdevbranchmake test-fuzzer FUZZERTEST=-T10s(349 tests passed)make test-zstream ZSTREAM_TESTTIME=-T10s(807 legacy API and 561 new API tests passed)make test-decodecorpus DECODECORPUS_TESTTIME=-T10(1,424 tests passed)cc @terrelln