Crate perf_event

source ·
Expand description

A performance monitoring API for Linux.

This crate provides access to processor and kernel counters for things like instruction completions, cache references and misses, branch predictions, context switches, page faults, and so on.

For example, to compare the number of clock cycles elapsed with the number of instructions completed during one call to println!:

use perf_event::{Builder, Group};
use perf_event::events::Hardware;

fn main() -> std::io::Result<()> {
    // A `Group` lets us enable and disable several counters atomically.
    let mut group = Group::new()?;
    let cycles = Builder::new().group(&mut group).kind(Hardware::CPU_CYCLES).build()?;
    let insns = Builder::new().group(&mut group).kind(Hardware::INSTRUCTIONS).build()?;

    let vec = (0..=51).collect::<Vec<_>>();

    group.enable()?;
    println!("{:?}", vec);
    group.disable()?;

    let counts = group.read()?;
    println!("cycles / instructions: {} / {} ({:.2} cpi)",
             counts[&cycles],
             counts[&insns],
             (counts[&cycles] as f64 / counts[&insns] as f64));

    Ok(())
}

This crate is built on top of the Linux perf_event_open system call; that documentation has the authoritative explanations of exactly what all the counters mean.

There are two main types for measurement:

  • A Counter is an individual counter. Use Builder to construct one.

  • A Group is a collection of counters that can be enabled and disabled atomically, so that they cover exactly the same period of execution, allowing meaningful comparisons of the individual values.

If you’re familiar with the kernel API already:

  • A Builder holds the arguments to a perf_event_open call: a struct perf_event_attr and a few other fields.

  • Counter and Group objects are just event file descriptors, together with their kernel id numbers, and some other details you need to actually use them. They’re different types because they yield different types of results, and because you can’t retrieve a Group’s counts without knowing how many members it has.

Call for PRs

Linux’s perf_event_open API can report all sorts of things this crate doesn’t yet understand: stack traces, logs of executable and shared library activity, tracepoints, kprobes, uprobes, and so on. And beyond the counters in the kernel header files, there are others that can only be found at runtime by consulting sysfs, specific to particular processors and devices. For example, modern Intel processors have counters that measure power consumption in Joules.

If you find yourself in need of something this crate doesn’t support, please consider submitting a pull request.

Modules

Events we can monitor or count.
Intercepting perf-event system calls, for testing and logging.

Structs

A builder for Counters.
The value of a counter, along with timesharing data.
A counter for one kind of kernel or hardware event.
A collection of counts from a Group of counters.
An iterator over the counter values in a Counts, returned by Group::read.
A group of counters that can be managed as a unit.