Skip to content

igzip: add an ICF encoder that looks up codes with AVX-512 VBMI on AMD - #452

Closed
ptweezy wants to merge 1 commit into
intel:masterfrom
ptweezy:igzip-icf-encode-vbmi
Closed

ptweezy wants to merge 1 commit into
intel:masterfrom
ptweezy:igzip-icf-encode-vbmi

Conversation

@ptweezy

@ptweezy ptweezy commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

encode_deflate_icf_06, the AVX-512 encoder for levels 1 to 3, gathers the lit/len and dist codes of each 16 ICF entries with two vpgatherdd, which are slow on AMD. This PR adds encode_deflate_icf_10, encode_df_06.asm built with USE_BYTE_PLANES, which looks up the codes of 64 entries at a time with VBMI byte permutes when a call has at least 288 entries, and gathers only the last entries.

Which CPUs run it

AMD processors with AVX-512 VBMI (Zen 4, Zen 5), at levels 1 to 3: an optional 7th function and 8th argument of mbin_dispatch_init6 select it only on AuthenticAMD processors with VBMI and the G2 features. Selected on every processor with VBMI, it made level 1 3-4% slower on Emerald Rapids and Granite Rapids; on Ice Lake, it made whole files 0.5% slower and 16 and 64 KB slices 1.4% and 2.2% faster (run, both builds on top of my other open changes).

Output does not change, and encode_deflate_icf_06 assembles to the same code as on master.

Related PRs

Results

MB/s, master → this PR, in-process A/B on GitHub runners (Zen 4, Zen 5, harness): median over all runs (two per runner) of the best of 11 rounds; in parentheses, the median over runs of the change in median-round throughput; Silesia files and 256 slices of the Silesia tar.

Runner CPU L1 L2 L3 L1, 16 KB slices L1, 64 KB slices
AMD EPYC 9V74 (Zen 4), 3 runners 537 → 552 (+2.8%) 511 → 523 (+2.5%) 302 → 307 (+1.5%) 395 → 405 (+2.5%) 496 → 511 (+3.0%)
AMD EPYC 9V45 (Zen 5), 6 runners 691 → 721 (+3.5%) 659 → 683 (+3.3%) 429 → 438 (+1.9%) 492 → 507 (+2.4%) 630 → 655 (+3.1%)

Testing

  • make check passes on Linux and natively on Windows 11 (mingw, Ryzen 7 9800X3D), alone and with igzip: save xmm6-xmm15 at 16-byte steps in the win64 ICF encoders #450. On Windows with igzip: save xmm6-xmm15 at 16-byte steps in the win64 ICF encoders #450, every call to the new encoder and its dispatcher keeps xmm6-xmm15, the callee-saved GPRs, rsp and DF.
  • encode_deflate_icf_10 and _06 return the same output and bit state for 45,000 random token streams ending at PROT_NONE pages; level 1-3 output is the same with either in the dispatch slot.
  • With faked CPUID and XGETBV (AMD, Intel, Hygon and malformed vendor strings, all combinations of the checked feature bits and XCR0 states), the dispatcher picks the new encoder only on AMD with AVX-512, VBMI and the G2 features.

encode_deflate_icf_06 gathers the lit/len and dist codes of 16 entries
with two vpgatherdd, which are slow on AMD Zen 4 and Zen 5.

Add encode_deflate_icf_10, built from encode_df_06.asm with
USE_BYTE_PLANES. When a call has at least 288 entries, it splits the two
code tables into byte planes on the stack and looks up the codes of 64
entries at a time with VBMI byte permutes: per plane, four 128-entry
lookups in the lit/len table, whose entry 512 is broadcast, and two
128-entry lookups and one 64-entry lookup in the dist table. Unpacks
interleave the planes back into dwords, the main loop loads the codes
of each 16 entries from there, and the last entries are still gathered.
The output does not change.

Emerald Rapids and Granite Rapids gather fast enough that the lookups
cost more than they save: a build that selected encode_deflate_icf_10
on every processor with AVX-512 VBMI made level 1 3% to 4% slower on
them. So give mbin_dispatch_init6 an optional 7th function for AMD
processors and an optional 8th argument with the CPUID.7.0:ECX
features it needs, and select encode_deflate_icf_10 that way with VBMI
and FLAGS_CPUID7_ECX_AVX512_G2. Other processors with AVX-512 keep
encode_deflate_icf_06.

Signed-off-by: Parker Loflin <parker@cronstable.dev>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant