有一个perf stat
选项"间隔打印";,给定为-I N
,其中N
是用于每N
毫秒打印计数器的毫秒间隔(N
>=10),其输出如下:
./perf stat -I 1000 -e event_name
time counts unit event_name
1.001177595 110 xyz
现在,我需要知道用于";计数单位";列,该列来自tools/perf/util/stat-display.c
。
TL;DR:格式说明符%'18.0f
,类型为double
的变量。
ltrace
+gdb
的简单检查揭示了用于打印的格式说明符:
$ uname -r
4.19.0-20-amd64
$ sudo ltrace -e '*fprintf*' perf_4.19 stat -I 1000 -e branch-misses
# timeperf_4.19->__fprintf_chk(0x7fcde97d1680, 1, 0x55a2b46652c0, 4 counts unit events
) = 32
1.001800886 perf_4.19->__fprintf_chk(0x7fcde97d1680, 1, 0x55a2b46596ab, 0x55a2b4770d89 2,536,128 ) = 19
perf_4.19->__fprintf_chk(0x7fcde97d1680, 1, 0x55a2b46596be, 4 ) = 5
perf_4.19->__fprintf_chk(0x7fcde97d1680, 1, 0x55a2b46582ba, 25branch-misses ) = 25
perf_4.19->__fprintf_chk(0x7fcde97d1680, 1, 0x55a2b46582ba, 35
...
$ sudo gdb --pid $(pidof perf_4.19)
(gdb) b __fprintf_chk
Breakpoint 1 at 0x7fd72c20de60: file fprintf_chk.c, line 26.
(gdb) c
Continuing.
Breakpoint 1, ___fprintf_chk (fp=0x7fd72c2c1680 <_IO_2_1_stderr_>, flag=1, format=0x556d2f5cd6ab "%'18.0f%s") at fprintf_chk.c:26
26 fprintf_chk.c: No such file or directory.
(gdb) x/s 0x556d2f5cd6ab
0x556d2f5cd6ab: "%'18.0f%s"
$ cd linux_source
$ git describe --tags
v4.19
$ rg -g 'tools/perf/**/*' -F "%'18.0f"
tools/perf/builtin-stat.c
1081: fmt = floor(sc) != sc ? "%'18.2f%s" : "%'18.0f%s";
这里是Linux v4.19的源代码,这里是最新的v5.18.12:
static void abs_printout(struct perf_stat_config *config,
struct aggr_cpu_id id, int nr, struct evsel *evsel, double avg)
{
FILE *output = config->output;
double sc = evsel->scale;
const char *fmt;
if (config->csv_output) {
fmt = floor(sc) != sc ? "%.2f%s" : "%.0f%s";
} else {
if (config->big_num)
fmt = floor(sc) != sc ? "%'18.2f%s" : "%'18.0f%s"; // <===
else
fmt = floor(sc) != sc ? "%18.2f%s" : "%18.0f%s";
}
aggr_printout(config, evsel, id, nr);
fprintf(output, fmt, avg, config->csv_sep);
// ...
}
使用的函数是fprintf
,格式说明符是%'18.2f
或%'18.0f
,具体取决于是否有小数要打印。打印发生在此处,打印的变量为double avg
。