Skip to content

Thaumy/perf-event-open

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

304 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

perf-event-open

Full-featured support for the perf_event_open syscall.

Crates.io MIT licensed

perf_event_open is a Linux system call widely used in performance monitoring, which provides access to the hardware Performance Monitoring Unit (PMU), allowing us to count and sample performance events. It is the core of the perf tool and many other performance engineering utilities.

Example

Count how many instructions executed for the (inefficient) fibonacci calculation and samples the user stack for it.

use perf_event_open::config::{Cpu, Opts, Proc, SampleOn, Size};
use perf_event_open::count::Counter;
use perf_event_open::event::hw::Hardware;

// Count retired instructions on current process, all CPUs.
let event = Hardware::Instr;
let target = (Proc::CURRENT, Cpu::ALL);

let mut opts = Opts::default();
opts.sample_on = SampleOn::Freq(1000); // 1000 samples per second.
opts.sample_format.user_stack = Some(Size(8)); // Dump 8-bytes user stack in sample.

let counter = Counter::new(event, target, opts).unwrap();
let sampler = counter.sampler(10).unwrap(); // Allocate 2^10 pages to store samples.

counter.enable().unwrap(); // Start the counter.
fn fib(n: usize) -> usize {
    match n {
        0 => 0,
        1 => 1,
        n => fib(n - 1) + fib(n - 2),
    }
}
std::hint::black_box(fib(30));
counter.disable().unwrap(); // Stop the counter.

let instrs = counter.stat().unwrap().count;
println!("{} instructions retired", instrs);

for it in sampler.iter() {
    println!("{:-?}", it);
}

On my machine, this gives the following output:

73973233 instructions retired
(Kernel, Sample { record_id: RecordId { .. }, user_stack: [16, 0, 0, 0, 0, 0, 0, 0], .. })
(Kernel, Sample { record_id: RecordId { .. }, user_stack: [16, 0, 0, 0, 0, 0, 0, 0], .. })
(Kernel, Sample { record_id: RecordId { .. }, user_stack: [16, 0, 0, 0, 0, 0, 0, 0], .. })
(Kernel, Sample { record_id: RecordId { .. }, user_stack: [16, 0, 0, 0, 0, 0, 0, 0], .. })
(Kernel, Sample { record_id: RecordId { .. }, user_stack: [16, 0, 0, 0, 0, 0, 0, 0], .. })
(User, Sample { record_id: RecordId { .. }, user_stack: [2, 0, 0, 0, 0, 0, 0, 0], .. })
(User, Sample { record_id: RecordId { .. }, user_stack: [1, 0, 0, 0, 0, 0, 0, 0], .. })
(User, Sample { record_id: RecordId { .. }, user_stack: [1, 0, 0, 0, 0, 0, 0, 0], .. })

For more use cases, please check the docs.

Compatibility

Any Linux kernel since 4.0 is supported.

Please use the Linux version features to ensure your binary is compatible with the target host kernel. These features are backwards compatible, e.g. linux-6.11 works with Linux 6.12 but may not work with Linux 6.10.

The legacy feature is compatible with the oldest LTS kernel that still in maintenance, or you can use the latest feature if you don't care about the kernel compatibility.

Calling Linux-specific functions (e.g., Counter::new) on non-Linux targets will return an error, but configuration and profiling result types are cross-platform compatible.

MSRV

We will keep the MSRV (minimum supported rust version) as little as possible if no dependencies require a higher MSRV, currently 1.80.0.

License

This project is licensed under the MIT license.

About

Full-featured support for the `perf_event_open` syscall.

Topics

Resources

License

Stars

Watchers

Forks

Contributors

Languages