Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
30 changes: 30 additions & 0 deletions benchmarks/results-20261011/baseline-build.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"command": [
"cc",
"-D_GNU_SOURCE",
"-ggdb",
"-Wall",
"-pthread",
"-Werror",
"-DXXH_STATIC_LINKING_ONLY",
"-fPIC",
"-DSPLINTERDB_PLATFORM_DIR=platform_linux",
"-O3",
"-ffast-math",
"-flto",
"-march=native",
"-DKVBENCH_CLOSE_HAS_FORCE",
"-I",
"/home/rob/projects/splinterdb/.cache/projects-20261011/baseline/include",
"/home/rob/projects/splinterdb/.cache/projects-20261011/baseline/benchmarks/kvbench.c",
"/home/rob/projects/splinterdb/.cache/projects-20261011/baseline/build/release/lib/libsplinterdb.a",
"-laio",
"-lxxhash",
"-lm",
"-lpthread",
"-o",
"/home/rob/projects/splinterdb/.cache/projects-20261011/baseline/build/release/bin/kvbench"
],
"source_sha256": "45cf9d2e1f74e90719885955d5a78651cc5c1d97cda2daed534a3c0cb07f48a9",
"binary_sha256": "40a04c4e24b3018cade6ad4a4fd2b3a39a8b4f050a364d1001c82ccc788e0d3e"
}
27 changes: 27 additions & 0 deletions benchmarks/results-20261011/build_kvbench.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/usr/bin/env python3
import argparse
import hashlib
import json
from pathlib import Path
import subprocess

p = argparse.ArgumentParser()
p.add_argument('tree', type=Path)
p.add_argument('--build-root', default='build')
a = p.parse_args()
tree = a.tree.resolve()
root = Path(__file__).resolve().parent.parent
source = root / 'baseline/benchmarks/kvbench.c'
binary = tree / a.build_root / 'release/bin/kvbench'
binary.parent.mkdir(parents=True, exist_ok=True)
command = ['cc', '-D_GNU_SOURCE', '-ggdb', '-Wall', '-pthread', '-Werror',
'-DXXH_STATIC_LINKING_ONLY', '-fPIC', '-DSPLINTERDB_PLATFORM_DIR=platform_linux',
'-O3', '-ffast-math', '-flto', '-march=native', '-DKVBENCH_CLOSE_HAS_FORCE',
'-I', str(tree / 'include'), str(source),
str(tree / a.build_root / 'release/lib/libsplinterdb.a'), '-laio', '-lxxhash', '-lm',
'-lpthread', '-o', str(binary)]
subprocess.run(command, check=True)
provenance = dict(command=command, source_sha256=hashlib.sha256(source.read_bytes()).hexdigest(),
binary_sha256=hashlib.sha256(binary.read_bytes()).hexdigest())
binary.with_suffix('.json').write_text(json.dumps(provenance, indent=2) + '\n')
print(binary)
72 changes: 72 additions & 0 deletions benchmarks/results-20261011/compare.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#!/usr/bin/env python3
"""Paired O_DIRECT public API runs; invoke through run_job.py benchmark."""
import argparse
import csv
import hashlib
import json
from pathlib import Path
import subprocess
import time

p = argparse.ArgumentParser()
p.add_argument('--project', required=True)
p.add_argument('--regime', choices=['resident', 'disk'], required=True)
p.add_argument('--seconds', type=int, default=5)
p.add_argument('--log', type=int, default=0)
p.add_argument('--baseline', type=Path)
p.add_argument('--campaign', default='')
p.add_argument('--fixture', type=Path)
p.add_argument('--candidate-binary', type=Path)
p.add_argument('--baseline-binary', type=Path)
p.add_argument('--phases', help='Comma-separated phase override')
a = p.parse_args()
root = Path(__file__).resolve().parent.parent
out = root / 'benchmarks' / a.project / (a.regime + '-log' + str(a.log) + ('-' + a.campaign if a.campaign else ''))
out.mkdir(parents=True, exist_ok=False)
trees = {'baseline': a.baseline or root / 'baseline', 'candidate': root / 'worktrees' / a.project}
phases = ['load:random', 'warm', 'point:uniform@1', 'point:uniform@8']
phases += [f'range:uniform:{length}@{threads}' for threads in [1, 8] for length in [1, 2, 10, 100, 10000]]
if a.phases:
phases = a.phases.split(',')
manifest = {'project': a.project, 'regime': a.regime, 'io': 'O_DIRECT', 'runs': []}
if a.fixture:
a.fixture = a.fixture.resolve(strict=True)
if 'load:random' in phases:
phases.remove('load:random')
# Reuse the identical immutable tree in each sample. Concurrent loading can
# produce different branch shapes, obscuring CPU-only query changes.
manifest['fixture'] = str(a.fixture)
manifest['fixture_sha256'] = subprocess.check_output(['sha256sum', str(a.fixture)], text=True).split()[0]
for index, version in enumerate(['baseline', 'candidate', 'candidate', 'baseline']):
binary = (a.baseline_binary if version == 'baseline' else a.candidate_binary) or trees[version] / 'build/release/bin/kvbench'
db = out / f'{index}-{version}.db'
if a.fixture:
subprocess.run(['cp', '--reflink=auto', '--sparse=always', str(a.fixture), str(db)], check=True)
argv = ['taskset', '-c', '0-11', str(binary), '--db', str(db), '--open' if a.fixture else '--create',
'--n', '200000' if a.regime == 'resident' else '2000000',
'--cache-mib', '128' if a.regime == 'resident' else '64',
'--disk-gib', '8', '--log', str(a.log), '--threads', '8',
'--mt-bg', '1', '--normal-bg', '3', '--memtable-mib', '4',
'--secs', str(a.seconds), '--warmup', '1', '--csv', str(out / 'results.csv'),
'--vtag', version, '--stag', a.regime, '--otag', str(index),
'--rep', str(index // 2), '--seed', '42', '--hang-secs', '60',
'--hang-dir', str(out), *phases]
record = dict(index=index, version=version, command=argv, started=time.time(),
binary_sha256=hashlib.sha256(binary.read_bytes()).hexdigest())
print(f'{a.project} {a.regime}: run {index + 1}/4 {version}', flush=True)
with (out / f'{index}-{version}.log').open('w') as log:
result = subprocess.run(argv, stdout=log, stderr=subprocess.STDOUT)
record.update(returncode=result.returncode, finished=time.time())
if db.exists():
record.update(db_allocated_bytes=db.stat().st_blocks * 512, db_apparent_bytes=db.stat().st_size)
manifest['runs'].append(record)
(out / 'manifest.json').write_text(json.dumps(manifest, indent=2) + '\n')
if result.returncode:
raise SystemExit(result.returncode)
with (out / 'results.csv').open() as stream:
rows = list(csv.DictReader(stream))
for row in rows:
for name in ['violations', 'errors']:
if name in row and int(row[name]) != 0:
raise RuntimeError('Correctness failures: ' + repr(row))
print('Completed', out, flush=True)
19 changes: 19 additions & 0 deletions benchmarks/results-20261011/disk-format-README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Metadata benchmark evidence, 2026-10-11

See ../../docs/on-disk-format.md for interpretation and validation.
CSV files and manifests preserve the raw samples, commands, timestamps and
binary/source provenance. Absolute paths in manifests identify the original
workspace. Database images and perf recordings are deliberately omitted.

The final implementation uses the scalar reader. `resident-log0` is the initial
reader; the two `*-final-singleload` campaigns and `resident-profile` precede
the scalar change. `resident-scalar-fixed` compares the old and final readers
on copies of exactly the same candidate image, with its own incompatible
baseline image. The retained runners document fixture sources and run order.
Baseline source is db3047a; the final implementation milestone is 33389f3.

Method caveat: `resident-scalar-fixed` used buffered fixture copies without an
explicit fsync before O_DIRECT open/warm/timing. Pending copy writeback could
confound those samples; it is not an established explanation of any difference.
The earlier fresh-create matrices did not use copied fixtures. Original evidence
is preserved without modification; there is no fsynced metadata repeat.
5 changes: 5 additions & 0 deletions benchmarks/results-20261011/disk-format-pre-scalar.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"src/routing_filter.c": "9de195af62910b303d59e09f3ecaf0006d1ce1867bbb0048b1eb29c0c04df4db",
"build/release/bin/kvbench": "99555661022785e5d3a494935e9b83cc3f6840a158024e6a68c20b370984b85f",
"build/release/lib/libsplinterdb.a": "cd4dd673c7e27e0f3356e4fdc67522a14b38c475dc4770be7324ab81470821f3"
}
Loading
Loading