Skip to content

umegbewe/zig-papi

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

zig-papi

Zig wrapper around libpapi.

Development

Under development.

Build Configuration

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 test

If 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/papi

You can also override the include and library paths directly:

zig build \
  -Dpapi-include=/path/to/include \
  -Dpapi-lib=/path/to/lib

Available 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

Quick Start

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

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.

Examples

The repository currently includes:

  • zig build run-example ... for basic instructions, cycles, and IPC
  • zig build run-load-store ... for load/store presets
  • zig build run-native-cache-misses ... for a native event string
  • zig build run-availability ... for preset availability checks

Examples:

zig build run-example
zig build run-availability

On 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

About

Zig wrapper around libpapi for hardware performance counters

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages