Zig wrapper around libpapi.
Under development.
Runtime counter availability is system-dependent. Some presets are unavailable on some CPUs, and some CI or container environments restrict access to performance counters entirely.
By default, build.zig uses pkg-config:
zig build
zig build testIf you want a specific local install, point Zig at it explicitly:
zig build -Dpapi-prefix=$HOME/.local/papi
zig build test -Dpapi-prefix=$HOME/.local/papiYou can also override the include and library paths directly:
zig build \
-Dpapi-include=/path/to/include \
-Dpapi-lib=/path/to/libAvailable build options:
-Dpapi-prefix=/path/to/prefix-Dpapi-include=/path/to/include-Dpapi-lib=/path/to/lib-Dpapi-use-pkg-config=true|false-Dpapi-rpath=true|false
const std = @import("std");
const papi = @import("zig_papi");
pub fn main() !void {
try papi.initLibrary();
var set = try papi.EventSet.init();
defer set.deinit();
try set.addPreset(.total_instructions);
try set.addPreset(.total_cycles);
try set.start();
var sum: u64 = 0;
for (0..10_000_000) |i| {
sum +%= i;
}
std.mem.doNotOptimizeAway(sum);
var values: [2]papi.CounterValue = undefined;
try set.stop(&values);
const instructions = values[0];
const cycles = values[1];
const ipc = @as(f64, @floatFromInt(instructions)) / @as(f64, @floatFromInt(cycles));
std.debug.print("instructions = {d}\n", .{instructions});
std.debug.print("cycles = {d}\n", .{cycles});
std.debug.print("IPC = {d:.3}\n", .{ipc});
}Native events are first-class in this wrapper because many systems expose far more native events than portable presets.
const event_name: [:0]const u8 = "perf::CACHE-MISSES";
if (papi.isNamedEventAvailable(event_name)) {
var set = try papi.EventSet.init();
defer set.deinit();
try set.addNative(event_name);
// ...
}The accepted string syntax comes from PAPI and libpfm, not Linux perf stat syntax. Use papi_native_avail or the included availability examples to discover names on your system.
The repository currently includes:
zig build run-example ...for basic instructions, cycles, and IPCzig build run-load-store ...for load/store presetszig build run-native-cache-misses ...for a native event stringzig build run-availability ...for preset availability checks
Examples:
zig build run-example
zig build run-availabilityOn hybrid or otherwise heterogeneous CPUs, pinning a benchmark to a specific CPU can make results easier to interpret:
taskset -c 0 zig build run-example