Skip to content

Performance on real data

AMD EPYC 9454: measured on older code

Measured at git v0.0.21a1-83-ga1a55ac (C sources sha256 5a0108f1b0c2, kernel-choice modules ce1cdafcbf56); this site was built from 6929bd75ab7a / 99941e0ecc68. The code changed since, so these numbers may no longer describe it. Re-run tools/bench_docs.py on that machine and commit its JSON.

Intel Xeon Gold 6248: measured on older code

Measured at git v0.0.21a1-83-ga1a55ac (C sources sha256 5a0108f1b0c2, kernel-choice modules ce1cdafcbf56); this site was built from 6929bd75ab7a / 99941e0ecc68. The code changed since, so these numbers may no longer describe it. Re-run tools/bench_docs.py on that machine and commit its JSON.

The two ID11 Eiger example files (sparse silicon, dense CeO2), each decoded on one core of each machine below, as bitshuffle-LZ4 in 8 kB blocks. 100 frames spread over each file were read into memory first (no file I/O is timed), then decoded in batches of 25 after one warmup batch; the best of 3 passes is shown. GB = 10^9 bytes. Compressed GB/s counts the bitshuffle-LZ4 bytes consumed, pixels GB/s the decompressed frame (pixels x bytes per pixel): their ratio is the compression ratio. Pipelines are the automatic choice on each machine, from the same build.

Both files share one approximate calibration, calib.poni (no spatial distortion), so the matrices are the same for every case: 75 um pixels, 0.139514 m distance, wavelength 2.84401e-11 m. Masked pixels: mask.h5 of the example data.

Machines

machine measured (UTC) build compiler Python, numpy, pyFAI data
AMD EPYC 9454 2026-10-14 17:28 0.0.22a1 v0.0.21a1-83-ga1a55ac gcc (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0 3.12.15, 2.5.3, 2026.9.0 real_data_epyc-9454.json
Intel Xeon Gold 6248 2026-10-14 17:07 0.0.22a1 v0.0.21a1-83-ga1a55ac gcc (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0 3.12.15, 2.5.3, 2026.9.0 real_data_xeon-gold-6248.json

Frames per second

data set operation AMD EPYC 9454 Intel Xeon Gold 6248
silicon sparsify 1770.2 820.4
silicon 1D 1032.2 615.0
silicon 1D no-split 1412.4 754.2
silicon 1D fine 789.2 498.5
silicon 2D 777.3 468.2
silicon 2D+rings 1302.9 721.7
ceo2 sparsify 437.7 186.9
ceo2 1D 108.1 47.9
ceo2 1D no-split 232.0 105.8
ceo2 1D fine 83.9 45.7
ceo2 2D 72.9 31.5
ceo2 2D+rings 330.8 153.2

Operations

operation what is timed
sparsify chunk2sparse: decode, mask and threshold to (values, indices)
1D chunk2sparseCSC, pyFAI 1D bbox matrix (r_mm, one bin per pixel width)
1D no-split chunk2sparseCSC, pyFAI 1D no-split matrix: a histogram, every pixel in one bin with weight 1 (r_mm, one bin per pixel width)
1D fine chunk2sparseCSC, pyFAI 1D bbox matrix with 6000 bins (r_mm): a fine split, several bins per pixel
2D chunk2sparseCSC, pyFAI 2D bbox matrix (q_nm^-1, one radial bin per pixel width x 72 azimuthal bins)
2D+rings chunk2sparseCSC, 8 LaB6 ring windows x 72 azimuthal bins summed from the 2D matrix, the windows sized to hold ~8 % of the unmasked pixels

silicon: sparse photon counting, uint16

silicon_lz4.h5, dataset /entry_0000/ESRF-ID11/eiger/data: 250 frames of 2162 x 2068 uint16; compression 59.8; 268834 masked pixels. Sparse cut 0: 0.5 % of the unmasked pixels are above it and go to the sparse output (mean over the timed frames).

matrix bins entries pixels with an entry bins per pixel (mean, max)
1D 1542 9655790 100 % 2.30, 3
1D no-split 1542 4202182 100 % 1.00, 1
1D fine 6000 25427825 100 % 6.05, 7
2D 1542 x 72 9835464 100 % 2.34, 88
2D+rings 8 x 72 375415 8.8 % 1.02, 2
operation machine frames/s compressed GB/s pixels GB/s
sparsify AMD EPYC 9454 1770.2 0.265 15.83
sparsify Intel Xeon Gold 6248 820.4 0.123 7.34
1D AMD EPYC 9454 1032.2 0.154 9.23
1D Intel Xeon Gold 6248 615.0 0.092 5.50
1D no-split AMD EPYC 9454 1412.4 0.211 12.63
1D no-split Intel Xeon Gold 6248 754.2 0.113 6.74
1D fine AMD EPYC 9454 789.2 0.118 7.06
1D fine Intel Xeon Gold 6248 498.5 0.075 4.46
2D AMD EPYC 9454 777.3 0.116 6.95
2D Intel Xeon Gold 6248 468.2 0.070 4.19
2D+rings AMD EPYC 9454 1302.9 0.195 11.65
2D+rings Intel Xeon Gold 6248 721.7 0.108 6.45

ceo2: dense powder rings, uint32

ceo2_lz4.h5, dataset /entry_0000/ESRF-ID11/eiger/data: 72 frames of 2162 x 2068 uint32; compression 4.6; 268834 masked pixels. Sparse cut 150: 1.3 % of the unmasked pixels are above it and go to the sparse output (mean over the timed frames).

matrix bins entries pixels with an entry bins per pixel (mean, max)
1D 1542 9655790 100 % 2.30, 3
1D no-split 1542 4202182 100 % 1.00, 1
1D fine 6000 25427825 100 % 6.05, 7
2D 1542 x 72 9835464 100 % 2.34, 88
2D+rings 8 x 72 375415 8.8 % 1.02, 2
operation machine frames/s compressed GB/s pixels GB/s
sparsify AMD EPYC 9454 437.7 1.720 7.83
sparsify Intel Xeon Gold 6248 186.9 0.735 3.34
1D AMD EPYC 9454 108.1 0.425 1.93
1D Intel Xeon Gold 6248 47.9 0.188 0.86
1D no-split AMD EPYC 9454 232.0 0.912 4.15
1D no-split Intel Xeon Gold 6248 105.8 0.416 1.89
1D fine AMD EPYC 9454 83.9 0.330 1.50
1D fine Intel Xeon Gold 6248 45.7 0.180 0.82
2D AMD EPYC 9454 72.9 0.286 1.30
2D Intel Xeon Gold 6248 31.5 0.124 0.56
2D+rings AMD EPYC 9454 330.8 1.300 5.92
2D+rings Intel Xeon Gold 6248 153.2 0.602 2.74

The conveyor on AMD EPYC 9454 + NVIDIA L40S

The conveyor (src/conveyor, threads) on 250 files of WAu5um_DT3 (ID11 Eiger 4M, uint16, scans 0001-0014 of /data/id11/nanoscope/blc12454/id11/WAu5um/WAu5um_DT3), 57.2 GB compressed, copied to /dev/shm first, so that the file system and the network are not timed; the results are dropped (a null sink). The same files for every point, in the order of the table; workers and their readers share 12 cores. The GPU points ran twice before the CPU points and twice after them. Operations: sparsify, the pixels above a cut of 1 (masked: the pixels at the dtype maximum of the first frame); 1d-nosplit, the same, and a pyFAI 1D no-split matrix (a histogram: one bin per pixel, weight 1). The matrices are built for that mask with the approximate geometry of tools/calib.poni: the work of an integration of this detector, not a calibrated pattern of these files. Measured 2026-10-14 17:12 UTC, build 0.0.22a1 v0.0.21a1-83-ga1a55ac; conveyor_epyc-9454-l40s.json.

pass decoder operation workers frames/s frames/s per CPU worker compressed GB/s worker cores seconds
gpu1 GPU sparsify 1 10064 2.30 1.0 24.8
gpu1 GPU sparsify 2 14632 3.35 1.9 17.1
gpu1 GPU sparsify 4 17090 3.91 3.6 14.6
gpu1 GPU 1d-nosplit 1 7791 1.78 1.0 32.1
gpu1 GPU 1d-nosplit 2 11097 2.54 1.9 22.5
gpu1 GPU 1d-nosplit 4 11265 2.58 3.7 22.2
gpu2 GPU sparsify 1 10070 2.30 1.0 24.8
gpu2 GPU sparsify 2 14645 3.35 1.9 17.1
gpu2 GPU sparsify 4 16958 3.88 3.6 14.7
gpu2 GPU 1d-nosplit 1 7748 1.77 1.0 32.3
gpu2 GPU 1d-nosplit 2 11012 2.52 1.9 22.7
gpu2 GPU 1d-nosplit 4 11196 2.56 3.7 22.3
cpu CPU sparsify 4 3975 994 0.91 4.0 62.9
cpu CPU sparsify 8 7640 955 1.75 7.7 32.7
cpu CPU sparsify 12 11228 936 2.57 11.2 22.3
cpu CPU 1d-nosplit 4 2840 710 0.65 4.0 88.0
cpu CPU 1d-nosplit 8 5339 667 1.22 7.7 46.8
cpu CPU 1d-nosplit 12 7730 644 1.77 11.2 32.3
gpu3 GPU sparsify 1 10057 2.30 1.0 24.9
gpu3 GPU sparsify 2 14608 3.34 1.9 17.1
gpu3 GPU sparsify 4 16947 3.88 3.6 14.8
gpu3 GPU 1d-nosplit 1 7772 1.78 1.0 32.2
gpu3 GPU 1d-nosplit 2 10988 2.51 1.9 22.8
gpu3 GPU 1d-nosplit 4 11271 2.58 3.7 22.2
gpu4 GPU sparsify 1 10014 2.29 1.0 25.0
gpu4 GPU sparsify 2 14650 3.35 1.9 17.1
gpu4 GPU sparsify 4 16930 3.87 3.6 14.8
gpu4 GPU 1d-nosplit 1 7828 1.79 1.0 31.9
gpu4 GPU 1d-nosplit 2 11053 2.53 1.9 22.6
gpu4 GPU 1d-nosplit 4 11205 2.56 3.7 22.3

Written by tools/bench_docs.py and tools/bench_race.py; one JSON per machine in docs/bench/.

Generated by tools/generate_docs.py from bslz4_to_sparse 0.0.22a2 (git v0.0.22-13-g610ed27, sources sha256 6929bd75ab7a).