Files
app/README.md
T
2026-07-17 17:10:35 -05:00

192 lines
7.0 KiB
Markdown

# fossbench
fossbench is an open-source CPU benchmark with nine assembly workloads and a
small C driver. It measures each workload twice: once on a single core and once
across every available core. The final report includes separate single-core and
multicore scores.
The repository currently builds an executable named `fossmark` for ARM64,
x86-64, and 32-bit big-endian PowerPC. The C driver handles timing, memory,
threads, output, and scoring. Performance-sensitive kernels live in
architecture-specific backend files.
## Workloads
| Test | What it measures |
|---|---|
| Integer math | 64-bit multiplication, division, shifts, and bit operations |
| Floating point math | Scalar double-precision multiplication, addition, division, and square roots |
| Prime numbers | A sieve of Eratosthenes up to 2,000,000 |
| Extended instructions | 128-bit SIMD integer and floating point work using NEON or SSE2 |
| Compression | An LZ77 match finder over a 4 MiB generated corpus |
| Encryption | ChaCha20 with 20 rounds over a 1 MiB buffer |
| Physics | Direct-sum gravity for 512 bodies |
| Sorting | In-place heapsort of one million 32-bit integers |
| Memory latency | Dependent pointer chasing through a private cache-exceeding cycle |
The benchmark increases each test's iteration count until one run takes at
least two seconds. It then keeps the fastest of three runs. Each kernel returns
a checksum, and fossbench stops if repeated runs produce different results.
During the multicore pass, every thread gets its own mutable workspace. This
keeps the kernels free of data races and prevents shared scratch buffers from
distorting the result.
## Build and run
You need a C compiler, GNU Make, pthreads, and the system math library.
```sh
make
make bench
```
`make` builds a binary for the host at
`dist/fossmark-<os>-<arch>`. `make bench` builds that binary and runs it.
Other targets are available for explicit platforms and architectures:
```sh
make linux-arm64
make linux-amd64
make linux-ppc32be
make macos-arm64
make macos-amd64
make all
```
`make all` builds both Linux targets. Cross-compilation requires a suitable
toolchain. Override the target compiler when its name differs from the default:
```sh
make linux-arm64 CC_ARM64=aarch64-linux-gnu-gcc
make linux-amd64 CC_AMD64=x86_64-linux-gnu-gcc
make linux-ppc32be CC_PPC32BE=powerpc-linux-gnu-gcc
```
Apple Clang can build either macOS architecture with `-arch`. Windows timing
and allocation code exists in the driver, but the Makefile does not include a
Windows target and the x86-64 assembly currently follows the System V ABI.
Run the benchmark with extra per-test details by passing `--verbose`:
```sh
./dist/fossmark-linux-amd64 --verbose
```
The exact filename depends on the host platform and architecture.
At startup, fossmark reports the detected CPU model, physical cores, logical
threads, installed memory, operating system, architecture, and compiler. At the
end it prints the composite scores and total benchmark duration, then asks
whether to upload the result. Uploading is opt-in and requires an API token in
the environment:
```sh
FOSSMARK_API_TOKEN=your_token ./dist/fossmark-linux-amd64
```
The API base URL is defined by `FM_API_BASE_URL` in `src/main.c` and defaults to
`http://localhost:8080`. A release build can override it without editing the
source:
```sh
make CFLAGS='-O2 -Wall -Wextra -DFM_API_BASE_URL=\"http://bench.example.com\"'
```
The built-in uploader currently supports plain HTTP. An HTTPS production URL
will require TLS support (or submission through a TLS-terminating local proxy).
## Continuous integration and releases
Pushing a Git tag runs the GitHub Actions build and correctness tests. If they
succeed, the workflow creates a GitHub Release named `Release <tag name>` with
Linux archives for AMD64, ARM64, and PPC32 big-endian, macOS archives for AMD64
and ARM64, and a `SHA256SUMS` file.
## Scores
Each workload receives a score relative to a reference rate:
```text
test score = 10000 * measured rate / reference rate
```
The single-core and multicore totals are weighted geometric means of the nine
test scores. Both passes use the same reference rates and weights, so their
ratio gives a direct view of scaling across the machine's available cores.
| Test | Weight |
|---|---:|
| Integer math | 20% |
| Memory latency | 16% |
| Compression | 14% |
| Sorting | 12% |
| Extended instructions | 11% |
| Floating point math | 9% |
| Encryption | 8% |
| Prime numbers | 6% |
| Physics | 4% |
The reference rates, weights, target score, workload sizes, calibration floor,
and repeat count are compile-time constants in `src/main.c`. Changing them
creates a different benchmark profile, so scores from that build should not be
compared with scores from the default build.
Memory latency is displayed as nanoseconds per access, but its score uses the
underlying pointer-chase throughput. Latency results are sensitive to memory
placement and operating-system activity, so some variation between runs is
normal.
## Architecture support
The kernel backends use only baseline instructions for their architecture:
* `src/fossmark.S` uses ARMv8-A and NEON under AAPCS64.
* `src/fossmark_x86_64.S` uses baseline x86-64 and SSE2 under the System V ABI.
* `src/fossmark_ppc32.c` is endian-safe and keeps a baseline 32-bit PowerPC
fallback. At runtime, the extended-instruction test uses Paired Singles when
the device-tree `compatible` property begins with `nintendo,`; otherwise it
selects VSX, AltiVec, or the scalar fallback in that order according to
Linux `AT_HWCAP`.
The PPC32 build uses a 2 MiB pointer-chase cycle, which exceeds the 750CL's L2
cache while keeping peak benchmark memory consumption below 32 MiB. Other
architectures retain the default 16 MiB cycle.
The assembly kernel files contain no system calls or calls into the C library.
The same ARM64 source can be assembled for Linux, macOS, Windows, and BSD object formats.
The current x86-64 source supports Linux, macOS, and the BSDs that use the
System V calling convention.
One binary cannot run on every supported target because operating systems and
architectures use different executable formats and instruction sets. Build a
separate binary for each operating system and architecture pair.
## Tests
The correctness suite checks all nine kernels against C reference
implementations, known answers, or invariants. Most checks also run concurrently
on every available core to catch shared-state and reentrancy bugs.
```sh
make test
```
The suite covers the RFC 8439 ChaCha20 test vector, prime counts, sorting output,
physics momentum, pointer-chase behavior, and deterministic results. It exits
with a nonzero status if any check fails.
## Source layout
```text
src/main.c portable benchmark driver and scoring
src/fossmark.S ARM64 kernels
src/fossmark_x86_64.S x86-64 kernels
src/fossmark_ppc32.c PPC32 big-endian kernels
src/fossmark_ppc32_ext.S optional PPC32 PS, VSX, and AltiVec kernels
src/test_kernels.c correctness suite
Makefile native and cross-build targets
dist/ generated binaries
```