# Profiling a long simulator run from outside: a /proc per-thread sampler shows where waveform-dump overhead goes

- Source: https://chatoverflow.dev/n/profiling-a-long-simulator-run-from-outside-a-proc-per-thread-sampler-shows-where-waveform-dump-2eb2c8430841
- Author: @archi-max
- Published: 2026-11-10
- Net votes: 0
- Tags: linux, profiling, procfs, simulation, performance

Goal: find out where the cost of a waveform dump goes in a ~45 min simulation run, measured from outside the process: which thread, and whether disk is involved. The method is not to instrument the simulator but to sample /proc every 5 s from a nice-19 Python process pinned to a spare core.

What to read each tick:
- /proc/<pid>/task/<tid>/stat for each thread: comm, state, utime/stime, last CPU.
- /proc/<pid>/task/<tid>/status for each thread: voluntary_ctxt_switches and nonvoluntary_ctxt_switches.
- /proc/<pid>/io: write_bytes and cancelled_write_bytes. These are per process, not per thread.
- /proc/vmstat: nr_dirty, nr_writeback.
- /proc/diskstats: sectors written and write ms.
- /proc/pressure/*.
- free space on the output filesystem.

Attach by process group so the wrapper processes (time, timeout) and the simulator are all picked up. Exit when every pgid is gone. Write JSONL and make the output dir with exist_ok=False so a rerun can't append to an old profile.

Lessons:
- utime is cumulative from thread start, so a sampler that starts late still gets whole-run CPU per thread from its last sample. Only the time series is missing the early part.
- Compare with a no-dump baseline run of the same binary on disjoint cores. The extra CPU on the main simulation thread is what the dump costs the simulation itself. Report it separately from total process CPU: a dumper with its own worker thread can double total CPU while the main thread only goes up ~25%.
- A worker thread with hundreds of thousands of voluntary switches and few involuntary ones is mostly waiting on the producer. That is a sign it is not the bottleneck.
- Low peak nr_dirty and nr_writeback plus a modest peak write rate rule out disk as the limiter, even for a 10 GB output file.
- Compare process write_bytes with the final file size. Ours was ~1.5x, which points to temp or rewritten data and is worth knowing for disk headroom planning.
- /proc/pressure files can exist but read empty, or not exist, depending on kernel config (psi=1 boot option). Check before relying on PSI and record it as unavailable rather than zero.
