I’ve been trying to reimplement (steal) some code from Andrew’s poop library. But i can’t seem to get any readings from the perf monitoring events, it always returns 0. I can’t really figure out why, i tried running my code as sudo as well but no dice. Andrew’s poop library works fine so my system configuration should allow it.
for (perf_measurements, &self.perf_fds) |measurement, *perf_fd| {
var attr: std.os.linux.perf_event_attr = .{
.type = PERF.TYPE.HARDWARE,
.config = @intFromEnum(measurement.config),
.flags = .{
.disabled = true,
.exclude_kernel = true,
.exclude_hv = true,
.inherit = true,
.enable_on_exec = true,
},
};
perf_fd.* = std.posix.perf_event_open(&attr, 0, -1, self.perf_fds[0], PERF.FLAG.FD_NO_GROUP) catch |err| {
std.debug.panic("unable to open perf event: {s}\n", .{@errorName(err)});
};
_ = std.os.linux.ioctl(perf_fd.*, PERF.EVENT_IOC.ENABLE, @intFromPtr(perf_fd));
}
_ = std.os.linux.ioctl(self.perf_fds[0], PERF.EVENT_IOC.DISABLE, PERF.IOC_FLAG_GROUP);
_ = std.os.linux.ioctl(self.perf_fds[0], PERF.EVENT_IOC.RESET, PERF.IOC_FLAG_GROUP);
self.benchmark.start_ns = self.benchmark.timer.read();
//
// Some testing code.
//
const end_ns = self.benchmark.timer.read() - self.benchmark.start_ns;
_ = std.os.linux.ioctl(self.perf_fds[0], PERF.EVENT_IOC.DISABLE, PERF.IOC_FLAG_GROUP);
self.benchmark.samples_buf[self.cur_sample] = .{
.wall_time = end_ns,
.cpu_cycles = readPerfFd(self.perf_fds[0]),
.instructions = readPerfFd(self.perf_fds[1]),
.cache_references = readPerfFd(self.perf_fds[2]),
.cache_misses = readPerfFd(self.perf_fds[3]),
.branch_misses = readPerfFd(self.perf_fds[4]),
};
for (&self.perf_fds) |*perf_fd| {
std.posix.close(perf_fd.*);
perf_fd.* = -1;
}