
Patches sent out to the Linux kernel mailing list today can provide much more efficient Zstd compression and decompression by addressing a very unfortunate oversight in the existing code.
Linux developer Usama Arif noted that the in-kernel Zstd code decides at run-time when creating a context for compression or decompression whether to pick the generic code path or the one making use of BMI2 instructions. The BMI2 bit manipulation instruction set is found with Intel Haswell and newer or AMD Excavator and newer processors. For the most part, the AMD and Intel CPUs of the past decade.
While run-time detection itself isn’t bad to allow falling back to generic code for older CPUs, doing so each and every time a new context is created is redundant. Short of like some wild CPU bugs, you shouldn’t lose BMI2 support after your system is booted and in operation. Probing for BMI2 is taking two serializing CPUD instructions with unconditional VM exits.
Where this situation becomes very bad is that this detection ends up being a very hot code path. SquashFS ends up calling it for every block it decompresses while EROFS, Btrfs, and F2FS all initialize a context per-operation. The crypro/zstd code also initializes a context per operation. So for every block with SquashFS or every operation elsewhere, it ends up with the two costly serializing CPUID instructions for finding out if there is BMI2 instructions supported on the CPU.
Usama Arif found that with the three patches to just probe BMI2 CPU support only once, it yield a 71% reduction in decompression time and a 18% reduction in compression time for a crypto_acomp benchmark.
The patches are out for review in the Linux kernel mailing list.