This RFC proposes adding optional support for the crc-fast library in PHP's ext/hash extension, enabling SIMD-accelerated CRC-32 and CRC-64 computation. When enabled via a new --with-crc-fast configure flag, this integration delivers up to 233× faster CRC throughput on ARM (aarch64) and ~4× on x86_64, while also adding support for CRC-64/NVME - a checksum algorithm PHP cannot currently compute natively.
PHP's current CRC implementation in ext/hash has two significant limitations:
On x86_64, PHP uses hardware CRC instructions for crc32c, achieving reasonable throughput (~27 GiB/s on Intel Sapphire Rapids). However, on aarch64, an increasingly popular server architecture (AWS Graviton, Apple Silicon, Ampere Altra), PHP falls back to table-based software computation, yielding only ~0.4 GiB/s. This is a 233× performance gap compared to what the hardware is capable of.
CRC-64/NVME (also known as CRC-64/ROCKSSOFT or CRC-64/WE) is the checksum algorithm:
aws-smithy-checksums)
PHP applications interacting with AWS S3 that need CRC-64/NVME checksums must currently rely on workarounds. There is no way to compute this checksum using hash() or any other built-in PHP function.
These limitations affect PHP applications that:
Add optional crc-fast library support to ext/hash via a new configure flag:
./configure --with-crc-fast
When enabled, the following changes take effect:
All existing CRC-32 hash algorithms registered in ext/hash gain SIMD-accelerated computation transparently. The affected algorithms and their hash() names are:
hash() name | Algorithm | Notes |
|---|---|---|
crc32 | CRC-32/BZIP2 (byte-reversed) | PHP's idiosyncratic “crc32”; see Legacy Behavior |
crc32b | CRC-32/ISO-HDLC | Standard CRC-32 |
crc32c | CRC-32/ISCSI | Castagnoli, already HW-accelerated on x86_64 |
All accelerated variants produce identical output to the current implementations. This is a pure performance optimization with no behavioral change.
The following CRC-64 variants are registered, covering all widely-used CRC-64 algorithms:
hash() name | Algorithm |
|---|---|
crc64nvme | CRC-64/NVME |
crc64ecma | CRC-64/ECMA-182 |
crc64iso | CRC-64/GO-ISO |
crc64xz | CRC-64/XZ |
crc64redis | CRC-64/REDIS |
crc64ms | CRC-64/MS |
When --with-crc-fast is not specified or libcrc_fast is not installed, PHP builds and behaves exactly as it does today. The new CRC-64 algorithms are not available, and CRC-32 uses the existing implementations.
crc-fast is a Rust library that provides:
PCLMULQDQ/VPCLMULQDQ on x86_64 and PMULL on aarch64libcrc_fast.so / libcrc_fast.dylib) via a stable C ABIThe library is:
aws-smithy-checksums)
Benchmarks comparing PHP's current ext/hash CRC-32/ISO-HDLC (crc32b) throughput against crc-fast, measured on 1 GiB input:
| Platform | PHP (current) | With crc-fast | Speedup |
|---|---|---|---|
| Apple M3 Ultra | ~0.4 GiB/s | ~99.6 GiB/s | 233× |
| AWS Graviton4 | ~0.4 GiB/s | ~56.7 GiB/s | 141× |
| AWS Graviton3 | ~0.4 GiB/s | ~27.2 GiB/s | 68× |
| Platform | PHP (current) | With crc-fast | Speedup |
|---|---|---|---|
| Intel Sapphire Rapids | ~27.0 GiB/s | ~108.3 GiB/s | 4× |
| AMD EPYC Genoa (Zen4) | ~13.6 GiB/s | ~53.7 GiB/s | 4× |
| Platform | Throughput |
|---|---|
| Apple M3 Ultra | ~70.0 GiB/s |
| Intel Sapphire Rapids | ~54.6 GiB/s |
| AWS Graviton4 | ~36.1 GiB/s |
The aarch64 improvement is the most dramatic because PHP currently has no hardware-accelerated CRC path on ARM. The x86_64 improvements come from the 8-at-a-time folding approach and AVX-512 VPCLMULQDQ usage on supporting processors.
PHP's hash('crc32', ...) computes CRC-32/BZIP2 with byte-reversed output, which differs from the CRC-32 implementation in most other languages and from PHP's own crc32() function. This is a long-standing quirk documented in the PHP manual.
The crc-fast library accounts for this via a dedicated CRC_32_PHP algorithm constant that exactly reproduces PHP's existing behavior. No output changes occur for any existing algorithm.
The following equivalences are preserved:
// These continue to produce identical results with or without crc-fast: hash('crc32', $data); // CRC-32/BZIP2, byte-reversed (PHP's quirk) hash('crc32b', $data); // CRC-32/ISO-HDLC (standard CRC-32) hash('crc32c', $data); // CRC-32/ISCSI (Castagnoli) crc32($data); // CRC-32/ISO-HDLC (native function, unaffected)
None. The feature is entirely opt-in via --with-crc-fast. When disabled, PHP is unchanged. When enabled, existing CRC-32 algorithms produce identical output at higher throughput, and new CRC-64 algorithm names are additive.
PHP 8.6 (next minor release targeting the master branch).
None. The change is internal to ext/hash.
None. The ext/hash public API is unchanged. Extensions that register custom hash algorithms are unaffected.
None.
None proposed. Algorithm selection uses string names via the existing hash() API.
No new INI settings. The feature is controlled entirely at compile time via --with-crc-fast.
Primary Vote requiring a 2/3 majority to accept the RFC:
Keep this updated with features that were discussed on the mail lists.
If there are major changes to the initial proposal, please include a short summary with a date or a link to the mailing list announcement here, as not everyone has access to the wikis' version history.