Skip to content

Benchmark fast_float with and without FASTFLOAT_ROUNDS_TO_NEAREST - #433

Merged
lemire merged 1 commit into
mainfrom
benchmark-rounds-to-nearest
Nov 9, 2026
Merged

lemire merged 1 commit into
mainfrom
benchmark-rounds-to-nearest

Conversation

@lemire

@lemire lemire commented Nov 9, 2026

Copy link
Copy Markdown
Member

Stacked on #432. This PR targets its branch and should be merged after it.

realbenchmark now times each parsing loop twice: once with the default fast_float, and once compiled with FASTFLOAT_ROUNDS_TO_NEAREST. The second set of lines is labeled assume nearest.

The macro version lives in a separate file, benchmarks/benchmark_rtn.cpp. That file renames the namespace (#define fast_float fast_float_rtn) before including fast_float. Without the rename, the two configurations would define the same inline functions differently in one binary, which is an ODR violation: the linker could silently keep either version. With it, nm shows separate fast_float:: and fast_float_rtn:: symbols, and the rounding-mode probe (rounds_to_nearest()::fmin) exists only in the default one. The timed loops are in the same file as the parsing, so both versions are inlined the same way.

Results on an Intel Xeon Gold 6548N (Emerald Rapids)

Linux (RHEL 10), pinned to one core, ASCII inputs. Each cell shows Mfloat/s, then instructions and cycles per float.

GCC 14.3

file type default assume nearest
canada 64-bit 91.0 Mf/s, 194.8 i/f, 38.3 c/f 93.9 Mf/s, 193.5 i/f, 37.1 c/f
canada 32-bit 92.9 Mf/s, 204.1 i/f, 37.6 c/f 94.5 Mf/s, 203.2 i/f, 36.9 c/f
mesh 64-bit 204.5 Mf/s, 94.7 i/f, 16.9 c/f 203.5 Mf/s, 88.9 i/f, 17.2 c/f
mesh 32-bit 175.2 Mf/s, 110.0 i/f, 19.9 c/f 183.9 Mf/s, 106.4 i/f, 19.0 c/f

Clang 21

file type default assume nearest
canada 64-bit 79.9 Mf/s, 238.8 i/f, 43.7 c/f 80.3 Mf/s, 238.0 i/f, 43.4 c/f
canada 32-bit 79.9 Mf/s, 245.3 i/f, 43.7 c/f 79.7 Mf/s, 245.2 i/f, 43.7 c/f
mesh 64-bit 161.1 Mf/s, 131.8 i/f, 21.7 c/f 152.5 Mf/s, 122.8 i/f, 22.9 c/f
mesh 32-bit 138.6 Mf/s, 150.3 i/f, 25.2 c/f 140.7 Mf/s, 145.1 i/f, 24.8 c/f

The macro always saves instructions: up to 6% on mesh, where most numbers take the fast path, and less than 1% on canada, where most do not. Speed changes by a few percent at most, in either direction. The one slowdown is with Clang on mesh (64-bit): 9 fewer instructions per float, but 1.2 more cycles.

realbenchmark now also times the parsing loops compiled with
FASTFLOAT_ROUNDS_TO_NEAREST (benchmark_rtn.cpp). That file renames the
fast_float namespace so that both configurations coexist in one binary
without an ODR violation.
@lemire
lemire changed the base branch from rounds-to-nearest-macro to main November 9, 2026 17:12
@lemire
lemire merged commit 8ec5968 into main Nov 9, 2026
65 checks passed
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