added scopes
This commit is contained in:
parent
b5dad13bd7
commit
c7cfa18ce9
|
|
@ -0,0 +1,131 @@
|
||||||
|
// pscopes
|
||||||
|
//
|
||||||
|
// a tiny scope based profiling library
|
||||||
|
//
|
||||||
|
// as well as contains info for arbitrary timestamping and timestamp resolution
|
||||||
|
|
||||||
|
const timestampTicks = if (builtin.target.cpu.arch == .x86_64) aarch64_ticks else rdtsc;
|
||||||
|
|
||||||
|
pub inline fn rdtsc_fenced() u64 {
|
||||||
|
var hi: u32 = 0;
|
||||||
|
var low: u32 = 0;
|
||||||
|
|
||||||
|
asm (
|
||||||
|
\\rdtsc
|
||||||
|
\\mfence
|
||||||
|
: [low] "={eax}" (low),
|
||||||
|
[hi] "={edx}" (hi),
|
||||||
|
);
|
||||||
|
return (@as(u64, hi) << 32) | @as(u64, low);
|
||||||
|
}
|
||||||
|
|
||||||
|
// rdtsc actually gets read
|
||||||
|
pub inline fn rdtsc() u64 {
|
||||||
|
var hi: u32 = 0;
|
||||||
|
var low: u32 = 0;
|
||||||
|
|
||||||
|
asm (
|
||||||
|
\\rdtsc
|
||||||
|
: [low] "={eax}" (low),
|
||||||
|
[hi] "={edx}" (hi),
|
||||||
|
);
|
||||||
|
return (@as(u64, hi) << 32) | @as(u64, low);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn aarch64_ticks() u64 {
|
||||||
|
return asm volatile ("mrs %[ret], CNTVCT_EL0"
|
||||||
|
: [ret] "=r" (-> u64),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn aarch64_freq() u64 {
|
||||||
|
return asm volatile ("mrs %[ret], CNTFRQ_EL0"
|
||||||
|
: [ret] "=r" (-> u64),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const TimingScope = struct {
|
||||||
|
// value in tsc ticks
|
||||||
|
startTsc: u64,
|
||||||
|
endTsc: ?u64 = null,
|
||||||
|
|
||||||
|
context: *ScopesContext,
|
||||||
|
|
||||||
|
pub inline fn init(c: *ScopesContext) @This() {
|
||||||
|
return .{
|
||||||
|
.startTsc = rdtsc(),
|
||||||
|
.context = c,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn duration(self: *@This()) ?f64 {
|
||||||
|
_ = self;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn end(self: *@This()) void {
|
||||||
|
self.endTsc = rdtsc();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const ScopesContext = struct {
|
||||||
|
allocator: std.mem.Allocator,
|
||||||
|
ticksPerMs: ?f64 = null,
|
||||||
|
timer: std.time.Timer,
|
||||||
|
|
||||||
|
pub fn timingScope(self: *@This()) TimingScope {
|
||||||
|
_ = self;
|
||||||
|
}
|
||||||
|
|
||||||
|
// calibrates the ticks per second divider.
|
||||||
|
// spins for 1 ms then compares against the monotonic timer
|
||||||
|
// should be called once every second
|
||||||
|
pub fn calibrate(self: *@This()) void {
|
||||||
|
if (builtin.target.cpu.arch == .x86_64) {
|
||||||
|
self.timer.reset();
|
||||||
|
const startStamp = rdtsc();
|
||||||
|
while (self.timer.read() < std.time.ns_per_ms) {}
|
||||||
|
const endStamp = rdtsc();
|
||||||
|
|
||||||
|
self.ticksPerMs = @floatFromInt((endStamp - startStamp));
|
||||||
|
} else if (builtin.target.cpu.arch == .aarch64) {
|
||||||
|
self.ticksPerMs = @as(f64, @floatFromInt(aarch64_freq())) / 1000;
|
||||||
|
} else {
|
||||||
|
// not ticking
|
||||||
|
// unreachable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||||
|
const self = try allocator.create(@This());
|
||||||
|
self.* = .{
|
||||||
|
.allocator = allocator,
|
||||||
|
.timer = try std.time.Timer.start(),
|
||||||
|
};
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn destroy(self: *@This()) void {
|
||||||
|
self.allocator.destroy(self);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
test "calibrate scoes" {
|
||||||
|
const allocator = std.testing.allocator;
|
||||||
|
|
||||||
|
const scopes = try ScopesContext.create(allocator);
|
||||||
|
defer scopes.destroy();
|
||||||
|
scopes.calibrate();
|
||||||
|
|
||||||
|
std.debug.print("calibration ticksPerMs = {d}\n", .{scopes.ticksPerMs.?});
|
||||||
|
scopes.calibrate();
|
||||||
|
std.debug.print("calibration ticksPerMs = {d}\n", .{scopes.ticksPerMs.?});
|
||||||
|
scopes.calibrate();
|
||||||
|
std.debug.print("calibration ticksPerMs = {d}\n", .{scopes.ticksPerMs.?});
|
||||||
|
scopes.calibrate();
|
||||||
|
std.debug.print("calibration ticksPerMs = {d}\n", .{scopes.ticksPerMs.?});
|
||||||
|
scopes.calibrate();
|
||||||
|
std.debug.print("calibration ticksPerMs = {d}\n", .{scopes.ticksPerMs.?});
|
||||||
|
}
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
const builtin = @import("builtin");
|
||||||
Loading…
Reference in New Issue