Skip to content

Measurement model

What a metric includes, and when two records may be compared. For an introduction with plots, see Understand the result.

Each metric is:

text
resource × lifecycle phase × execution regime × scope × method × statistic

For example: startup, import, first execution and steady-state time are four measurements. Julia heap bytes, native heap bytes, process RSS and GPU memory are four resources.

Required context

Every measurement definition states:

  • metric ID, unit, collector and definition version;

  • phase: resolve, install, precompile, startup, import, first execution, steady state, endurance, shutdown;

  • regime: clean depot, cached depot, fresh process, warm process, steady state;

  • scope: expression, method, feature, task, process, process tree, interface, service, database, device;

  • clock or counter source, and whether collection is exact, repeated, sampled, static or estimated;

  • sample and aggregation semantics;

  • whether compilation, GC, child processes, GPU synchronization, loopback and protocol overhead are included;

  • expected perturbation and required privileges;

  • runtime, source, dependency, artifact, platform, hardware and environment provenance;

  • a semantic outcome proving both candidates did equivalent work.

Values are comparable only when their measurement definitions and comparison keys permit it.

Comparability in a bundle

Suite bundles retain controller thread count, hardware fingerprint, local Git revision/branch/dirty state, and SHA-256 fingerprints of the effective Project and Manifest.

  • Different OS, architecture, Julia thread count or known hardware makes a comparison incomparable.

  • A changed runtime or resolved environment is a warning, because controlled campaigns may vary one deliberately.

  • Older bundles with missing fingerprints carry less comparability information.

Measurement families

  • Warm CPU execution — latency, throughput, CPU user/system, GC. BenchmarkTools, Chairmarks.

  • Startup and import — bare startup, activation, using, __init__, extension load. Fresh processes, @time_imports.

  • Compilation and TTFX — first execution, inference, codegen, recompilation, dispatch. Trace flags, SnoopCompile, JET.

  • Precompile and imagesPkg.precompile, cache hit/miss, image size. PrecompileTools, PackageCompiler.

  • Inference and invalidation — inference time, unstable returns, dispatch sites, invalidation trees. JET, SnoopCompile.

  • CPU profiles — self/cumulative samples, task/thread, Julia and native frames. Profile, PProf, Speedscope.

  • Scheduling and waiting — runnable/running/waiting tasks, locks, saturation. Wall-time profile.

  • Julia allocation and GC — bytes/count per operation, sites, pauses. Profile.Allocs, @allocated, AllocCheck.

  • Heap and process memory — Julia heap, retained objects, RSS/commit peak, page faults. Heap snapshots, process sampler.

  • Microarchitecture — cycles, instructions, IPC, cache/TLB/branch misses, migrations. LinuxPerf, LIKWID.

  • File and storage I/O — logical/physical bytes, ops, latency, warm/cold cache. App counters plus OS adapters.

  • Network and services — payload/interface/wire bytes, packets, retries, latency. Workload counters, isolated interface.

  • GPU/accelerator — device compile, launch, kernel, transfer, sync, VRAM. CUDA/AMDGPU, vendor profilers.

  • Parallel/distributed — speedup, efficiency, scaling, serialization, imbalance. Thread/process matrices, MPI.

  • Energy — joules/run, joules/op, power. RAPL/LIKWID.

  • Domain algorithm — growth with size, time-to-solution, accuracy, iterations. Workload-declared outcomes.

  • Load/endurance — tail latency, backpressure, errors, recovery. Isolated staged-load scenarios.

Static analyzers emit diagnostics, not timings. A JET or AllocCheck finding can guide attribution; it is never presented as measured cost.

Process and external memory

Set :process_resources => true on a feature to record a resource envelope around its backend collection.

  • WindowsWorkingSetSize, lifetime PeakWorkingSetSize, PrivateUsage.

  • LinuxVmRSS, lifetime VmHWM, smaps_rollup private mappings.

  • Other platforms — all three unavailable.

  • Unsupported fields are absent, never zero.

  • The envelope surrounds the whole collection, not each sample.

  • A process peak is never reset; new_lifetime_peak records only its growth during collection.

  • BenchmarkTools memory/allocs columns remain Julia allocation evidence, separate from process RSS.

A feature that owns native memory can name a :external_memory_probe callback implementing perfchecker-external-memory/1. See Process memory.

Network accounting

Five scopes, weakest to strongest attribution:

  1. application — payload bytes and operations the workload reports.

  2. host_interface — OS interface deltas; contaminated by unrelated traffic.

  3. isolated_interface — the same counters inside a dedicated namespace or container.

  4. process_tree — bytes/packets attributed by ETW/eBPF to the worker.

  5. wire — packet capture including transport overhead; opt-in.

Package CI gates require level 3, 4 or a controlled interface. Latency is always labelled with its context (in-process, loopback, client end-to-end, server, DNS/TLS, scheduler wait).

Native dependency closure

Four layers:

text
declared package → resolved artifact → loaded native image → spawned process / service

dependency_evidence() snapshots the first layer's current process. ProbeSpec adds a feature-owned functional check inside the prepared worker. Successful resolution alone never proves an ABI or symbol is usable. Julia allocation counters never claim to cover native allocators.

Julia runtimes

JuliaRuntimeSpec adds a runtime axis separate from package versions.

  • Moving selectors (release, rc, nightly) are probed in a fresh process; the exact version, commit, bindir and LLVM version are frozen before workers start.

  • run_julia_runtime_campaign compares bundles without treating a runtime difference as an automatic incompatibility.

  • Failures are phase-classified: resolver vs precompile vs runtime crash vs suite failure vs launch vs missing report.

Two campaign styles:

  • Strict runtime attribution keeps source, dependencies, workload and machine fixed while Julia changes.

  • Realistic compatibility resolves independently under each runtime and reports dependency differences without attributing them to Julia.

Open source · Report an issue · Contributions welcome