From 8680a59f5a88bde7ab97d3e6f6ad043b21f2348b Mon Sep 17 00:00:00 2001 From: Nathan Daly Date: Sat, 13 Dec 2025 21:27:31 -0700 Subject: [PATCH 1/6] Beginnings of Reinterpret Benchmark --- src/BaseBenchmarks.jl | 1 + src/reinterpret/ReinterpretBenchmarks.jl | 61 ++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 src/reinterpret/ReinterpretBenchmarks.jl diff --git a/src/BaseBenchmarks.jl b/src/BaseBenchmarks.jl index cac6797..66d6c27 100644 --- a/src/BaseBenchmarks.jl +++ b/src/BaseBenchmarks.jl @@ -23,6 +23,7 @@ const MODULES = Dict("array" => :ArrayBenchmarks, "parallel" => :ParallelBenchmarks, "problem" => :ProblemBenchmarks, "random" => :RandomBenchmarks, + "reinterpret" => :ReinterpretBenchmarks, "scalar" => :ScalarBenchmarks, "shootout" => :ShootoutBenchmarks, "simd" => :SIMDBenchmarks, diff --git a/src/reinterpret/ReinterpretBenchmarks.jl b/src/reinterpret/ReinterpretBenchmarks.jl new file mode 100644 index 0000000..28de517 --- /dev/null +++ b/src/reinterpret/ReinterpretBenchmarks.jl @@ -0,0 +1,61 @@ +module ReinterpretBenchmarks + +using BenchmarkTools + +const SUITE = BenchmarkGroup() + +@noinline function measure_reinterpret(::Type{T1}, x::T2) where {T1, T2} + a = @noinline reinterpret(T1, x) + b = @noinline reinterpret(T2, a) + return a, b +end + +function bench_reinterpret(::Type{T1}, x::T2, N=1000) where {T1, T2} + for _ in 1:N + global a, b = measure_reinterpret(T1, x) + GC.safepoint() + Threads.atomic_fence() + end +end + +# --- Packed Types --------------------------------------- +g = addgroup!(SUITE, "packed_types") + +# Define extra primitive types for benchmarking +primitive type Int24 3 * 8 end +primitive type Int40 5 * 8 end +primitive type Int48 6 * 8 end +primitive type Int56 7 * 8 end + +primitive type Int136 17 * 8 end +primitive type Int144 18 * 8 end + +primitive type Int384 48 * 8 end +primitive type Int392 49 * 8 end +primitive type Int400 50 * 8 end + +primitive type Int1024 128 * 8 end + +for B in (3, 4, 6, 7, 17, 18, 48, 49, 50, 128) + let T = eval(Symbol("Int$(B*8)")) + g[B] = @benchmarkable bench_reinterpret($T, $(ntuple(i->UInt8(i), B)), 1000) + end +end + +function perf_reinterpret_() + TUPLES = [ + (0x01, 1, 0x02), + (1.0, 2, 3.0, 4, 5.0, 6, 7.0, 8, 9.0, 10, 11.10, 12, 13.0), + (1, 0x0001, (0x01, 2, 0x01), 0x01, 1.0), + ntuple(i->0x01, 100), + ntuple(i->0x01, 228), + (0x01, 1, 2, ntuple(i->0x01, 100),), + ] + for tup in TUPLES + bench_normalization(tup) + end +end + +# SUITE["arrays"] = @benchmarkable perf_alloc_many_arrays() + +end # module From b6600e147a753dc6e3f4dda7c45a6095cb81caf1 Mon Sep 17 00:00:00 2001 From: Nathan Daly Date: Sat, 13 Dec 2025 21:57:42 -0700 Subject: [PATCH 2/6] Decent set of reinterpret benchmarks --- src/reinterpret/ReinterpretBenchmarks.jl | 65 ++++++++++++++++++------ 1 file changed, 49 insertions(+), 16 deletions(-) diff --git a/src/reinterpret/ReinterpretBenchmarks.jl b/src/reinterpret/ReinterpretBenchmarks.jl index 28de517..ec05047 100644 --- a/src/reinterpret/ReinterpretBenchmarks.jl +++ b/src/reinterpret/ReinterpretBenchmarks.jl @@ -23,39 +23,72 @@ g = addgroup!(SUITE, "packed_types") # Define extra primitive types for benchmarking primitive type Int24 3 * 8 end -primitive type Int40 5 * 8 end -primitive type Int48 6 * 8 end -primitive type Int56 7 * 8 end primitive type Int136 17 * 8 end -primitive type Int144 18 * 8 end primitive type Int384 48 * 8 end primitive type Int392 49 * 8 end -primitive type Int400 50 * 8 end primitive type Int1024 128 * 8 end -for B in (3, 4, 6, 7, 17, 18, 48, 49, 50, 128) +for B in (1, 2, 3, 8, 16, 17, 48, 49, 128) let T = eval(Symbol("Int$(B*8)")) - g[B] = @benchmarkable bench_reinterpret($T, $(ntuple(i->UInt8(i), B)), 1000) + g[B] = @benchmarkable bench_reinterpret($T, $(ntuple(i->UInt8(i), B))) end end -function perf_reinterpret_() - TUPLES = [ +g = addgroup!(SUITE, "padded_types") + +primitive type Int80 10 * 8 end +primitive type Int232 29 * 8 end +primitive type Int800 100 * 8 end +primitive type Int832 104 * 8 end +primitive type Int936 117 * 8 end +primitive type Int1824 228 * 8 end + +for tup in [ (0x01, 1, 0x02), - (1.0, 2, 3.0, 4, 5.0, 6, 7.0, 8, 9.0, 10, 11.10, 12, 13.0), (1, 0x0001, (0x01, 2, 0x01), 0x01, 1.0), - ntuple(i->0x01, 100), - ntuple(i->0x01, 228), (0x01, 1, 2, ntuple(i->0x01, 100),), ] - for tup in TUPLES - bench_normalization(tup) - end + B1 = sizeof(tup) + B2 = Base.packedsize(typeof(tup)) + T2 = eval(Symbol("Int$(B2*8)")) + g[B2, B1] = @benchmarkable bench_reinterpret($T2, $(tup)) +end + +g = addgroup!(SUITE, "mixed_tuples") + +for tup in [ + (1.0, 2, 3.0, 4, 5.0, 6, 7.0, 8, 9.0, 10, 11.10, 12, 13.0), + ntuple(i->(isodd(i) ? Int32(i) : Float32(i)), 25), + ntuple(i->(isodd(i) ? true : i % UInt8), 228), + ] + B1 = sizeof(tup) + B2 = Base.packedsize(typeof(tup)) + T2 = eval(Symbol("Int$(B2*8)")) + g[B2, B1] = @benchmarkable bench_reinterpret($T2, $(tup)) end -# SUITE["arrays"] = @benchmarkable perf_alloc_many_arrays() +g = addgroup!(SUITE, "padded_to_padded") + +for (tup, T2) in [ + # Same padding, different positions: + (0x01, 1, 0x02) => Tuple{Int32, Int16, Int32}, + (0x01, 1, 2, ntuple(i->0x01, 100),) => Tuple{UInt64, UInt8, Int64, NTuple{100,Int8}}, + # small padding to big + (1, 0x0001, (0x01, 2, 0x01), 0x01, 1.0) => + Tuple{Int16, Int8, Int64, Int8, Int64, Int64, Int8}, + # inverse: big padding to small + (0x0000, 0x01, 0x0000000000000002, 0x03, 0x0000000000000004, 0x0000000000000005, 0x06) => + Tuple{Int64, UInt16, Tuple{UInt8, Int64, UInt8}, UInt8, Float64}, + # exactly the same padding positions, just different types: + (0x01, 1, 0x02) => Tuple{Int8, Float64, Int8}, + ] + p = Base.packedsize(typeof(tup)) + B1 = sizeof(tup) + B2 = sizeof(T2) + g[p, B2, B1] = @benchmarkable bench_reinterpret($T2, $(tup)) +end end # module From e1074f9a11694a58cc882716911cb6210f4a4337 Mon Sep 17 00:00:00 2001 From: Nathan Daly Date: Sat, 13 Dec 2025 22:01:44 -0700 Subject: [PATCH 3/6] Add empty benchmarks --- src/reinterpret/ReinterpretBenchmarks.jl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/reinterpret/ReinterpretBenchmarks.jl b/src/reinterpret/ReinterpretBenchmarks.jl index ec05047..c70ad84 100644 --- a/src/reinterpret/ReinterpretBenchmarks.jl +++ b/src/reinterpret/ReinterpretBenchmarks.jl @@ -22,6 +22,7 @@ end g = addgroup!(SUITE, "packed_types") # Define extra primitive types for benchmarking +struct Int0 end primitive type Int24 3 * 8 end primitive type Int136 17 * 8 end @@ -31,7 +32,7 @@ primitive type Int392 49 * 8 end primitive type Int1024 128 * 8 end -for B in (1, 2, 3, 8, 16, 17, 48, 49, 128) +for B in (0, 1, 2, 3, 8, 16, 17, 48, 49, 128) let T = eval(Symbol("Int$(B*8)")) g[B] = @benchmarkable bench_reinterpret($T, $(ntuple(i->UInt8(i), B))) end @@ -60,6 +61,7 @@ end g = addgroup!(SUITE, "mixed_tuples") for tup in [ + ((), (((), ())), ()), (1.0, 2, 3.0, 4, 5.0, 6, 7.0, 8, 9.0, 10, 11.10, 12, 13.0), ntuple(i->(isodd(i) ? Int32(i) : Float32(i)), 25), ntuple(i->(isodd(i) ? true : i % UInt8), 228), @@ -73,6 +75,8 @@ end g = addgroup!(SUITE, "padded_to_padded") for (tup, T2) in [ + # Empty tuples: + ((), (((), ())), ()) => Tuple{Tuple{Tuple{}, Tuple{}}, Tuple{}, Tuple{Tuple{}}}, # Same padding, different positions: (0x01, 1, 0x02) => Tuple{Int32, Int16, Int32}, (0x01, 1, 2, ntuple(i->0x01, 100),) => Tuple{UInt64, UInt8, Int64, NTuple{100,Int8}}, From 34a16b62f21174c39cacef48581897f161353dcd Mon Sep 17 00:00:00 2001 From: Nathan Daly Date: Sat, 13 Dec 2025 22:11:59 -0700 Subject: [PATCH 4/6] Reduce redundant benchmark cases --- src/reinterpret/ReinterpretBenchmarks.jl | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/reinterpret/ReinterpretBenchmarks.jl b/src/reinterpret/ReinterpretBenchmarks.jl index c70ad84..8a81192 100644 --- a/src/reinterpret/ReinterpretBenchmarks.jl +++ b/src/reinterpret/ReinterpretBenchmarks.jl @@ -23,16 +23,11 @@ g = addgroup!(SUITE, "packed_types") # Define extra primitive types for benchmarking struct Int0 end -primitive type Int24 3 * 8 end - primitive type Int136 17 * 8 end - -primitive type Int384 48 * 8 end primitive type Int392 49 * 8 end - primitive type Int1024 128 * 8 end -for B in (0, 1, 2, 3, 8, 16, 17, 48, 49, 128) +for B in (0, 8, 17, 49, 128) let T = eval(Symbol("Int$(B*8)")) g[B] = @benchmarkable bench_reinterpret($T, $(ntuple(i->UInt8(i), B))) end From 12117c98c94f02a9473688c42f19b5c585aad436 Mon Sep 17 00:00:00 2001 From: Nathan Daly Date: Thu, 18 Dec 2025 14:27:37 -0700 Subject: [PATCH 5/6] 32-bit machine --- src/reinterpret/ReinterpretBenchmarks.jl | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/reinterpret/ReinterpretBenchmarks.jl b/src/reinterpret/ReinterpretBenchmarks.jl index 8a81192..e4bb3e9 100644 --- a/src/reinterpret/ReinterpretBenchmarks.jl +++ b/src/reinterpret/ReinterpretBenchmarks.jl @@ -43,9 +43,9 @@ primitive type Int936 117 * 8 end primitive type Int1824 228 * 8 end for tup in [ - (0x01, 1, 0x02), - (1, 0x0001, (0x01, 2, 0x01), 0x01, 1.0), - (0x01, 1, 2, ntuple(i->0x01, 100),), + (0x01, Int64(1), 0x02), + (Int64(1), 0x0001, (0x01, Int64(2), 0x01), 0x01, 1.0), + (0x01, Int64(1), Int64(2), ntuple(i->0x01, 100),), ] B1 = sizeof(tup) B2 = Base.packedsize(typeof(tup)) @@ -55,6 +55,7 @@ end g = addgroup!(SUITE, "mixed_tuples") +primitive type Int416 52 * 8 end for tup in [ ((), (((), ())), ()), (1.0, 2, 3.0, 4, 5.0, 6, 7.0, 8, 9.0, 10, 11.10, 12, 13.0), @@ -73,10 +74,10 @@ for (tup, T2) in [ # Empty tuples: ((), (((), ())), ()) => Tuple{Tuple{Tuple{}, Tuple{}}, Tuple{}, Tuple{Tuple{}}}, # Same padding, different positions: - (0x01, 1, 0x02) => Tuple{Int32, Int16, Int32}, - (0x01, 1, 2, ntuple(i->0x01, 100),) => Tuple{UInt64, UInt8, Int64, NTuple{100,Int8}}, + (0x01, Int64(1), 0x02) => Tuple{Int32, Int16, Int32}, + (0x01, Int64(1), Int64(2), ntuple(i->0x01, 100),) => Tuple{UInt64, UInt8, Int64, NTuple{100,Int8}}, # small padding to big - (1, 0x0001, (0x01, 2, 0x01), 0x01, 1.0) => + (Int64(1), 0x0001, (0x01, Int64(2), 0x01), 0x01, 1.0) => Tuple{Int16, Int8, Int64, Int8, Int64, Int64, Int8}, # inverse: big padding to small (0x0000, 0x01, 0x0000000000000002, 0x03, 0x0000000000000004, 0x0000000000000005, 0x06) => From d60366f65068a9f600c9225d654a4d2e0c6a3df7 Mon Sep 17 00:00:00 2001 From: Nathan Daly Date: Fri, 19 Dec 2025 08:59:02 -0700 Subject: [PATCH 6/6] add more 32-bit types --- src/reinterpret/ReinterpretBenchmarks.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/reinterpret/ReinterpretBenchmarks.jl b/src/reinterpret/ReinterpretBenchmarks.jl index e4bb3e9..814da91 100644 --- a/src/reinterpret/ReinterpretBenchmarks.jl +++ b/src/reinterpret/ReinterpretBenchmarks.jl @@ -55,7 +55,8 @@ end g = addgroup!(SUITE, "mixed_tuples") -primitive type Int416 52 * 8 end +primitive type Int416 52 * 8 end # For 32-bit +primitive type Int640 80 * 8 end # For 32-bit for tup in [ ((), (((), ())), ()), (1.0, 2, 3.0, 4, 5.0, 6, 7.0, 8, 9.0, 10, 11.10, 12, 13.0),