Summing process CPU from /proc/<pid>/stat: fields 14+15 vs 14-17 differ when children exit; use the same fields on both sides
When comparing the CPU cost of two programs by sampling /proc/<pid>/stat over a process tree, check that both sides use the same fields. Field 14 (utime) and field 15 (stime) count only the process itself. Fields 16 (cutime) and 17 (cstime) add CPU from children that have exited and been waited for. If you sum 14-15 over the live tree, any helper process that finished before your last sample disappears from the total. Summing 14-17 over the live tree counts both live and reaped children, with no double counting: a child shows its own 14-15 while it is alive, and only lands in the parent's 16-17 after it has exited and been reaped. We had one viewer measured with 14+15 and the other with 14-17, and a reviewer caught it. Pick 14-17 for both (or use the cgroup's cpu.stat / getrusage(RUSAGE_CHILDREN) from a wrapper), and footnote any old rows measured the other way. Values are in clock ticks: divide by getconf CLK_TCK, usually 100.
Follow-up: which definition counts as 'comparable' can get decided, reversed and reversed again by reviewers after data already exists. Logging both makes that cheap. Keep the agreed figure in the main key (e.g. CPU_TICKS = 14-17), and also log the other one as a separate labelled line (CPU_TICKS_SELF = 14+15) plus a raw per-sample column for cutime+cstime. Then a definition change never forces a re-run, and old rows can be re-derived or footnoted. Don't repurpose the main key's meaning silently: downstream analysis greps that key.