Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 135 additions & 6 deletions mbo/hash/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,133 @@ Everything between the markers is generated per machine by `publish` from the
committed bundles - regenerate it, don't hand-edit:

<!-- BEGIN mbo/hash benchmark results (generated by `hash_benchmark_report.py publish`; DO NOT EDIT) -->
<!-- bundles: mbo/hash/measurements/data/linux-x86-64-amd-ryzen-9-9950x-16-core-processor_10c_gcc-15_29b54ccd_20260715_182532.tgz mbo/hash/measurements/data/macos-arm64-apple-m5-pro_18c_clang-21_29b54ccd_20260715_191140.tgz -->
<!-- bundles: mbo/hash/measurements/data/linux-x86-64-amd-ryzen-9-9950x-16-core-processor_10c_clang-22_29b54ccd_20260716_194643.tgz mbo/hash/measurements/data/linux-x86-64-amd-ryzen-9-9950x-16-core-processor_10c_gcc-15_29b54ccd_20260715_182532.tgz mbo/hash/measurements/data/macos-arm64-apple-m5-pro_18c_clang-21_29b54ccd_20260715_191140.tgz -->

### AMD Ryzen 9 9950X 16-Core Processor · Linux · x86_64 · 10-core · clang-22 · 29b54ccd

<!-- AMD Ryzen 9 9950X 16-Core Processor · Linux · x86_64 · 10-core · clang-22 · 29b54ccd; mean of the 3 best of 9 reps -->

![mbo/hash 64-bit latency, AMD Ryzen 9 9950X 16-Core Processor · Linux · x86_64 · 10-core · clang-22 · 29b54ccd](measurements/charts/linux-x86-64-amd-ryzen-9-9950x-16-core-processor_clang-22_latency64.svg)

#### 64-bit latency (ns/hash at exact length, mean of the 3 best of 9 reps; lower is better)

| Length | mumbo | rapidhash | xxh3 | xxh64 | murmur3 | siphash24 | fnv1a | dumbo |
| -----: | -------: | --------: | ----: | ----: | ------: | --------: | -------: | -------: |
| 1 B | 1.33 | 1.48 | 1.70 | 2.01 | 3.06 | 7.94 | **0.39** | 1.25 |
| 3 B | 1.47 | 1.48 | 1.70 | 2.43 | 3.07 | 7.94 | **0.81** | 1.65 |
| 5 B | 1.28 | 1.47 | 1.65 | 2.54 | 2.20 | 5.05 | **1.17** | 1.22 |
| 7 B | 1.29 | 1.47 | 1.65 | 2.91 | 2.20 | 5.05 | 1.61 | **1.22** |
| 8 B | 1.28 | 1.47 | 1.64 | 2.19 | 2.20 | 6.02 | 1.27 | **1.22** |
| 11 B | **1.25** | 1.47 | 1.55 | 3.25 | 13.70 | 10.65 | 2.07 | 2.16 |
| 15 B | **1.24** | 1.47 | 1.55 | 3.63 | 2.58 | 6.14 | 3.25 | 1.79 |
| 16 B | **1.25** | 1.47 | 1.55 | 2.59 | 2.87 | 7.74 | 3.16 | 1.79 |
| 19 B | 1.75 | **1.66** | 1.92 | 3.92 | 14.41 | 10.94 | 4.28 | 2.48 |
| 22 B | 1.75 | **1.66** | 1.92 | 3.99 | 3.49 | 7.72 | 5.37 | 2.11 |
| 27 B | 1.76 | **1.66** | 1.92 | 4.36 | 4.64 | 11.36 | 6.88 | 2.88 |
| 32 B | 1.76 | **1.66** | 1.92 | 4.34 | 4.09 | 10.94 | 8.88 | 2.51 |
| 38 B | 2.11 | **1.95** | 2.82 | 5.89 | 4.58 | 10.95 | 11.61 | 3.06 |
| 47 B | 2.11 | **1.94** | 2.82 | 7.17 | 5.14 | 12.46 | 15.76 | 3.51 |
| 48 B | 2.11 | **1.94** | 2.82 | 5.83 | 5.15 | 14.16 | 15.70 | 3.51 |
| 63 B | 2.47 | **2.25** | 2.82 | 8.98 | 6.33 | 15.64 | 24.43 | 4.52 |
| 64 B | 2.47 | **2.25** | 2.82 | 5.32 | 6.47 | 17.36 | 24.63 | 4.50 |
| 127 B | 4.84 | **3.61** | 4.64 | 11.53 | 11.24 | 28.61 | 66.37 | 8.65 |
| 128 B | 5.40 | **3.61** | 4.59 | 7.12 | 11.49 | 30.21 | 66.38 | 8.65 |
| 256 B | 8.80 | **5.88** | 28.75 | 11.18 | 20.99 | 55.92 | 156.8 | 19.97 |
| 1 KiB | 35.85 | **17.15** | 40.67 | 34.89 | 80.08 | 210.0 | 703.3 | 104.9 |
| 4 KiB | 160.1 | **64.56** | 124.2 | 131.1 | 316.3 | 828.6 | 2885 | 471.4 |

![mbo/hash 64-bit throughput (Short), AMD Ryzen 9 9950X 16-Core Processor · Linux · x86_64 · 10-core · clang-22 · 29b54ccd](measurements/charts/linux-x86-64-amd-ryzen-9-9950x-16-core-processor_clang-22_throughput64_Short.svg)

#### 64-bit throughput, Short lengths (GiB/s over lengths <= max, mean of the 3 best of 9 reps; higher is better)

| max len | mumbo | rapidhash | xxh3 | xxh64 | murmur3 | siphash24 | fnv1a | dumbo |
| ------: | -------: | --------: | ---: | ----: | ------: | --------: | -------: | ----: |
| 8 B | 2.28 | 1.11 | 1.94 | 1.21 | 1.27 | 0.55 | **2.43** | 2.16 |
| 12 B | **4.29** | 3.64 | 3.54 | 2.07 | 2.04 | 0.83 | 2.88 | 3.10 |
| 16 B | **6.24** | 5.11 | 5.14 | 2.81 | 2.86 | 1.26 | 3.05 | 4.31 |
| 23 B | **7.04** | 6.60 | 6.33 | 3.45 | 3.35 | 1.54 | 2.99 | 5.17 |
| 31 B | **8.32** | 8.12 | 7.66 | 4.05 | 3.96 | 1.81 | 3.01 | 6.05 |
| 38 B | **8.20** | 8.02 | 7.46 | 3.96 | 3.88 | 1.78 | 2.87 | 5.96 |
| 53 B | **9.07** | 8.90 | 8.20 | 4.27 | 4.23 | 1.92 | 2.83 | 6.45 |
| 80 B | **9.07** | 8.91 | 8.19 | 4.32 | 4.24 | 1.92 | 2.79 | 6.45 |
| 128 B | **9.05** | 8.90 | 8.18 | 4.32 | 4.22 | 1.91 | 2.80 | 6.43 |

![mbo/hash 64-bit throughput (Web), AMD Ryzen 9 9950X 16-Core Processor · Linux · x86_64 · 10-core · clang-22 · 29b54ccd](measurements/charts/linux-x86-64-amd-ryzen-9-9950x-16-core-processor_clang-22_throughput64_Web.svg)

#### 64-bit throughput, Web lengths (GiB/s over lengths <= max, mean of the 3 best of 9 reps; higher is better)

| max len | mumbo | rapidhash | xxh3 | xxh64 | murmur3 | siphash24 | fnv1a | dumbo |
| ------: | -------: | --------: | ---: | ----: | ------: | --------: | ----: | ----: |
| 15 B | **4.86** | 4.16 | 4.03 | 2.33 | 2.37 | 1.02 | 3.05 | 3.69 |
| 28 B | 7.34 | **7.62** | 6.98 | 3.85 | 3.62 | 1.63 | 2.86 | 5.66 |
| 45 B | 11.4 | **11.9** | 9.99 | 5.05 | 5.16 | 2.32 | 2.70 | 7.84 |
| 75 B | 14.5 | **15.2** | 12.7 | 6.10 | 6.22 | 2.76 | 2.42 | 9.26 |
| 120 B | 16.2 | **17.5** | 14.7 | 7.14 | 6.90 | 3.02 | 2.14 | 9.73 |
| 220 B | 16.7 | **19.0** | 15.3 | 7.80 | 7.39 | 3.20 | 2.03 | 9.95 |
| 512 B | 17.1 | **20.5** | 14.3 | 8.57 | 7.73 | 3.30 | 1.89 | 9.63 |
| 2 KiB | 18.4 | **23.7** | 15.1 | 10.1 | 8.33 | 3.52 | 1.73 | 9.31 |
| 4 KiB | 18.2 | **23.2** | 14.7 | 9.93 | 8.25 | 3.47 | 1.73 | 9.26 |

![mbo/hash 128-bit latency, AMD Ryzen 9 9950X 16-Core Processor · Linux · x86_64 · 10-core · clang-22 · 29b54ccd](measurements/charts/linux-x86-64-amd-ryzen-9-9950x-16-core-processor_clang-22_latency128.svg)

#### 128-bit latency (ns/hash at exact length, mean of the 3 best of 9 reps; native-128 only; lower is better)

| Length | jumbo | xxh3 | murmur3 |
| -----: | --------: | -------: | ------: |
| 1 B | **2.23** | 2.34 | 3.07 |
| 3 B | 2.73 | **2.34** | 3.07 |
| 5 B | 2.37 | **1.96** | 2.16 |
| 7 B | 2.37 | **1.96** | 2.15 |
| 8 B | 2.18 | **1.96** | 2.16 |
| 11 B | **2.15** | 2.34 | 13.73 |
| 15 B | **2.15** | 2.34 | 2.63 |
| 16 B | **2.15** | 2.34 | 2.95 |
| 19 B | **2.66** | 2.94 | 14.33 |
| 22 B | **2.66** | 2.94 | 3.54 |
| 27 B | **2.66** | 2.94 | 4.66 |
| 32 B | **2.66** | 2.94 | 4.13 |
| 38 B | **3.22** | 3.83 | 4.65 |
| 47 B | **3.21** | 3.84 | 5.18 |
| 48 B | **3.21** | 3.84 | 5.21 |
| 63 B | **3.83** | 3.86 | 6.39 |
| 64 B | 4.36 | **3.84** | 6.53 |
| 127 B | 6.07 | **5.84** | 11.26 |
| 128 B | **5.26** | 5.78 | 11.53 |
| 256 B | **7.23** | 25.79 | 21.04 |
| 1 KiB | **20.86** | 37.90 | 80.09 |
| 4 KiB | **77.54** | 119.9 | 316.4 |

![mbo/hash 128-bit throughput (Short), AMD Ryzen 9 9950X 16-Core Processor · Linux · x86_64 · 10-core · clang-22 · 29b54ccd](measurements/charts/linux-x86-64-amd-ryzen-9-9950x-16-core-processor_clang-22_throughput128_Short.svg)

#### 128-bit throughput, Short lengths (GiB/s over lengths <= max, mean of the 3 best of 9 reps; higher is better)

| max len | jumbo | xxh3 | murmur3 |
| ------: | -------: | -------: | ------: |
| 8 B | 1.46 | **1.56** | 1.25 |
| 12 B | **2.62** | 2.59 | 2.02 |
| 16 B | **3.75** | 3.58 | 2.83 |
| 23 B | **4.60** | 4.33 | 3.32 |
| 31 B | **5.55** | 5.19 | 3.92 |
| 38 B | **5.47** | 5.10 | 3.84 |
| 53 B | **6.05** | 5.64 | 4.19 |
| 80 B | **6.05** | 5.63 | 4.20 |
| 128 B | **6.04** | 5.62 | 4.17 |

![mbo/hash 128-bit throughput (Web), AMD Ryzen 9 9950X 16-Core Processor · Linux · x86_64 · 10-core · clang-22 · 29b54ccd](measurements/charts/linux-x86-64-amd-ryzen-9-9950x-16-core-processor_clang-22_throughput128_Web.svg)

#### 128-bit throughput, Web lengths (GiB/s over lengths <= max, mean of the 3 best of 9 reps; higher is better)

| max len | jumbo | xxh3 | murmur3 |
| ------: | -------: | ---: | ------: |
| 15 B | **2.97** | 2.96 | 2.35 |
| 28 B | **5.08** | 4.81 | 3.59 |
| 45 B | **7.84** | 7.06 | 5.11 |
| 75 B | **9.93** | 9.11 | 6.17 |
| 120 B | **11.5** | 10.8 | 6.83 |
| 220 B | **12.7** | 11.7 | 7.31 |
| 512 B | **14.1** | 11.5 | 7.66 |
| 2 KiB | **16.6** | 12.8 | 8.28 |
| 4 KiB | **16.2** | 12.4 | 8.18 |

### AMD Ryzen 9 9950X 16-Core Processor · Linux · x86_64 · 10-core · gcc-15 · 29b54ccd

Expand Down Expand Up @@ -634,11 +760,14 @@ Reading the results:
be; `murmur3` (2011) fails the modern battery broadly; and `fnv1a` - the
algorithm family behind many `std::hash` implementations - passes 7 of 186
tests. Numbers worth remembering when defaulting to `std::hash`.
- The mumbo/jumbo family is the default in all forms; the extras remain
available for
canonical-value interop via `hash_extra.h` (`//mbo/hash:hash_extra_cc`,
which carries the third-party NOTICE obligations - see the repository-root
NOTICE).
- When build with `-march=znsver5` to enable `AVX-512` and any other instruction
that may optimize the code on an AMD ZEN 5 CPU, the `mumbo/jumbo` and `dumbo`
family actually performs incredibly well as can be seen in the first report
set which was measured with `--config=clang` `--copt=-march=znver5`.
- The `mumbo/jumbo` family is thus the default in all forms. The extras remain
available for canonical-value interop via `hash_extra.h` found in library
target `//mbo/hash:hash_extra_cc`. That target carries the third-party
[NOTICE](../../NOTICE).

### mumbo: the measured design iterations

Expand Down
14 changes: 14 additions & 0 deletions mbo/hash/hash_benchmark.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@
// every dispatch-tier boundary and SSO cutoff, for the complete dataset and
// the ns-vs-length graph.

#ifdef __linux__
# include <pthread.h>
# include <sched.h>
#endif // __linux__

#include <array>
#include <cmath>
#include <cstdint>
Expand Down Expand Up @@ -377,6 +382,15 @@ void RegisterAll(std::tuple<Algos...> /*algorithms*/) {
} // namespace mbo::hash

int main(int argc, char** argv) {
benchmark::MaybeReenterWithoutASLR(argc, argv); // NO ASLR

#ifdef __linux__
cpu_set_t set;
CPU_ZERO(&set);
CPU_SET(0, &set); // Pin to the first available core
pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &set);
#endif // __linux__

mbo::hash::RegisterAll(mbo::hash::algo::AllAlgorithms{});
benchmark::Initialize(&argc, argv);
// The build compiler is a first-class axis of a measurement (GCC vs Clang perf
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading