feat: control perf with fifo

This commit is contained in:
gmega 2025-12-22 18:41:22 -03:00
parent 4a0bff6b36
commit c4a15cdb90
No known key found for this signature in database
GPG Key ID: 6290D34EAD824B18
2 changed files with 66 additions and 21 deletions

49
benchmarks/perf.nim Normal file
View File

@ -0,0 +1,49 @@
# Simple utils for controlling perf tracing through fifos.
# After creating ack and control fifos with mkfifo, you can use this with:
#
# perf record -g \
# --delay -1 \
# --control fifo:./perf-ctl,./perf-ack \
# --call-graph dwarf \
# -F 99 \
# -o perf.data -- [command]
import std/strformat
import std/strutils
import pkg/questionable/results
type Perf* = object
ctl_file: File
ack_file: File
proc attach*(Perf: type, ctl_fifo: string, ack_fifo: string): ?!Perf =
var perf: Perf
if not open(perf.ctl_file, ctl_fifo, fmWrite):
return failure("Failed to open ctl fifo")
if not open(perf.ack_file, ack_fifo, fmRead):
return failure("Failed to open ack fifo")
success(perf)
proc detach*(self: Perf) =
self.ctl_file.close()
self.ack_file.close()
proc send*(self: Perf, cmd: string): ?!void =
self.ctl_file.write(cmd)
self.ctl_file.flushFile()
let response = self.ack_file.readLine()
# Ideally equality should work, but in practice we get some garbage
# characters sometimes.
if not ("ack" in response):
return failure(&"Error {response} received from perf")
success()
proc perfOn*(self: Perf): ?!void =
send(self, "enable")
proc perfOff*(self: Perf): ?!void =
send(self, "disable")

View File

@ -11,23 +11,7 @@ import pkg/codex/merkletree/codex
import pkg/codex/manifest
import pkg/codex/stores/[filestore, repostore]
let
PR_TASK_PERF_EVENTS_DISABLE {.
importc: "PR_TASK_PERF_EVENTS_DISABLE", header: "<linux/prctl.h>"
.}: cint
PR_TASK_PERF_EVENTS_ENABLE {.
importc: "PR_TASK_PERF_EVENTS_ENABLE", header: "<linux/prctl.h>"
.}: cint
proc prctl(
option: cint, args: varargs[culong]
): cint {.importc: "prctl", header: "<sys/prctl.h>".}
proc perfOn() =
assert prctl(PR_TASK_PERF_EVENTS_ENABLE) == 0
proc perfOff() =
assert prctl(PR_TASK_PERF_EVENTS_DISABLE) == 0
import ./perf
const
NBlocks = 163_840
@ -118,6 +102,12 @@ proc readData(
proc runRepostoreBench(
dataset: Dataset
): Future[void] {.async: (raises: [CatchableError]).} =
let perf = Perf.attach("./perf-ctl", "./perf-ack").expect(
"failed to locate perf ctl/ack files"
)
perf.perfOff().expect("failed to disable perf")
let
dir = createTempDir("repostore-bench", "")
store = newRepostore(dir)
@ -129,13 +119,19 @@ proc runRepostoreBench(
benchmark "repostore write data":
await writeData(dataset, store)
perf.perfOn().expect("failed to enable perf")
benchmark "repostore read data":
await writeData(dataset, store)
proc runFilestoreBench(
dataset: Dataset
): Future[void] {.async: (raises: [CatchableError]).} =
perfOff()
let perf = Perf.attach("./perf-ctl", "./perf-ack").expect(
"failed to locate perf ctl/ack files"
)
perf.perfOff().expect("failed to disable perf")
let
dir = createTempDir("filestore-bench", "")
@ -148,11 +144,11 @@ proc runFilestoreBench(
benchmark "filestore write data":
await writeData(dataset, store)
perfOn()
perf.perfOn().expect("failed to enable perf")
benchmark "filestore read data":
await readData(dataset, store)
let dataset = makeDataset(NBlocks, BlockSize).tryGet()
# waitFor runRepostoreBench(dataset)
waitFor runFilestoreBench(dataset)
waitFor runRepostoreBench(dataset)
#waitFor runFilestoreBench(dataset)