Skip to content

Latest commit

 

History

13 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

lang-bench

lang-bench is a reproducible benchmark suite for C, C++, Zig, Odin, and Rust on scientific-style workloads. It keeps algorithms, inputs, data layouts, and correctness checks as consistent as practical, then records the effects of compilers, optimization flags, threading libraries, and accelerator hardware.

The suite does not produce universal language rankings. Results depend on the processor, compiler version, target flags, workload size, and implementation details. The source and runner scripts define the benchmark behavior; docs/language-comparison.md contains measured results and discussion.

Workloads

Workload Implementations Focus
Sieve of Eratosthenes C++, Zig, Odin, Rust Integer loops, memory traffic, bounds-check elimination
Dense matrix multiply C++, Zig, Odin, Rust Cache behavior and floating-point loop optimization
Tiled matrix multiply C++, Zig, Odin, Rust Data layout, loop tiling, fast-math modes, LTO
Monte Carlo π C (GCC and Clang), Zig, Odin, Rust Multithreading and integer-kernel code generation
Trapezoid integration C (GCC and Clang), Zig, Odin, Rust Parallel reduction around a sin()-bound workload
Ray tracer C (GCC and Clang), Zig, Odin, Rust, OpenCL Threaded FP64 ray-sphere intersection and CPU/GPU behavior
CNN inference Python/OpenVINO on CPU, GPU, NPU Accelerator latency and throughput; separate from the language suite

C++ implements the single-threaded kernels and C implements the pthread-based workloads. GCC and Clang variants are built for workloads where compiler code generation can materially affect results.

Method

Each compiled benchmark:

  • uses the same algorithm, loop order, and data layout across implementations;
  • generates deterministic inputs instead of using the operating-system RNG;
  • verifies a checksum or numerical result before timings are compared;
  • keeps allocation and setup outside the timed section;
  • runs a warmup followed by multiple timed iterations;
  • emits median, mean, and sample standard deviation as JSON Lines; and
  • uses multi-second default workloads where practical to reduce scheduler and timer noise.

The default workloads are intentionally expensive and may take several minutes to complete. Use smaller environment overrides for a smoke test.

Requirements

The full native suite expects Linux with:

  • GCC (gcc, g++)
  • Clang
  • Zig
  • Odin
  • Rust and Cargo
  • Python 3
  • pthreads and libm
  • an OpenCL loader and working device for the GPU ray tracer

The optional OpenVINO experiment has separate Python dependencies and is not run by scripts/run_all.sh.

Record compiler versions, CPU model, operating system, available accelerators, and relevant environment variables with every result set. Results from one host should not be treated as portable rankings.

Build and run

git clone https://github.com/reneotten/lang-bench.git
cd lang-bench

./scripts/build_all.sh
./scripts/run_all.sh

Run selected workloads by name:

./scripts/run_all.sh sieve matmul
./scripts/run_all.sh monte_carlo integration
./scripts/run_all.sh raytrace

For a shorter validation run, override workload sizes before invoking the runner:

BENCH_ITERS=3 \
BENCH_WARMUP=1 \
BENCH_SIEVE_N=10000000 \
BENCH_MATMUL_N=512 \
BENCH_MATMUL_OPT_N=768 \
BENCH_MC_SAMPLES=100000000 \
BENCH_INT_N=10000000 \
BENCH_RT_W=1280 \
BENCH_RT_H=720 \
./scripts/run_all.sh

BENCH_THREADS=0 uses all logical CPUs. Set a positive value to compare thread counts. config.env lists the defaults; each benchmark also accepts workload-specific environment variables.

Results

Every implementation emits one JSON object. A complete run is saved to a timestamped file and copied to results/latest.jsonl:

results/run_YYYYMMDDTHHMMSSZ.jsonl
results/latest.jsonl

Summarize a result file with:

python3 scripts/summarize.py results/latest.jsonl

Generated results and binaries are ignored by Git so local measurements stay out of source history. JSON records include the workload name, implementation, input size, thread count, warmup and iteration counts, timings, and a correctness result. For example:

{
  "bench": "raytrace_par",
  "lang": "c",
  "n": 33177600,
  "threads": 8,
  "iters": 7,
  "warmup": 1,
  "times_ms": [63.804, 56.529, 57.987],
  "median_ms": 57.987,
  "mean_ms": 59.44,
  "stdev_ms": 3.846,
  "result": "sum_par=2931122.255531,sum_seq=2931122.253782,px=33177600"
}

CPU and OpenCL ray tracer

The ray tracer uses the same fixed scene and FP64 math in every implementation. Compare its checksum before comparing timings.

./scripts/build_all.sh
./scripts/run_all.sh raytrace

BENCH_RT_W=1920 BENCH_RT_H=1080 ./scripts/run_all.sh raytrace

The OpenCL headers needed for the host program are vendored under third_party/opencl/. Runtime still requires a system OpenCL loader and a compatible device driver.

Optional OpenVINO accelerator experiment

scripts/npu_bench.py builds two synthetic convolutional networks and measures inference latency on the OpenVINO CPU, GPU, and NPU plugins. It is an accelerator experiment rather than a hand-written language port.

python3 scripts/npu_bench.py

On Linux, Intel GPU/NPU access commonly requires membership in the render group. You can run the command in that group with:

sg render -c "python3 scripts/npu_bench.py"

Repository layout

benches/
  common/                 shared C and Zig timing helpers
  sieve/                  C++, Zig, Odin, Rust
  matmul/                 C++, Zig, Odin, Rust
  matmul_opt/             optimized C++, Zig, Odin, Rust
  monte_carlo/            C, Zig, Odin, Rust
  integration/            C, Zig, Odin, Rust
  raytrace/               C, Zig, Odin, Rust, OpenCL
scripts/
  build_all.sh            compile the native suite
  run_all.sh              run workloads and collect JSONL
  summarize.py            print result tables
  npu_bench.py            optional OpenVINO CPU/GPU/NPU experiment
docs/
  language-comparison.md  measured results and conclusions
  language-implementation-quickstart.md
                            language pickup guide
config.env                default workload sizes and iteration counts

Interpreting results

Compare checksums first, then wall time and variance. Speedup can mislead when sequential baselines differ. Workload size, compiler, CPU target, and loop structure can change relative results; document these conditions alongside any published comparison.

About

Fair, reproducible C/C++/Zig/Odin/Rust benchmarks for scientific workloads

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages