使用linux perf实用程序每秒报告计数器,如vmstat

时间:2016-11-10 06:29:44

标签: linux performancecounter perf

Linux中有perf command-linux实用程序来访问硬件性能监视计数器,它使用perf_events内核子系统。

perf本身基本上有两种模式:perf record / perf top来记录采样配置文件(例如每100000个cpu时钟周期或执行的命令),{{1} } mode报告应用程序(或整个系统)的循环/执行命令的总计数。

是否存在perf stat模式,以每秒(每3,5,10秒)的总计数打印系统范围或每CPU摘要,就像在perf和systat-中打印一样家庭工具(vmstatiostatmpstat ...如http://techblog.netflix.com/2015/11/linux-performance-analysis-in-60s.html中所列)?例如,对于循环和指令计数器,我将获得每秒系统(或每个CPU)的平均IPC。

是否有任何非sar -n DEV工具(在https://perf.wiki.kernel.org/index.php/Tutorialhttp://www.brendangregg.com/perf.html中)可以使用perf内核子系统获取此类统计信息?那么系统范围的每个进程IPC计算的分辨率为秒?

1 个答案:

答案 0 :(得分:1)

perf stat-I N个选项“interval-print”,其中N是毫秒间隔,每N毫秒(N> = 10)进行间隔计数器打印:http://man7.org/linux/man-pages/man1/perf-stat.1.html

  -I msecs, --interval-print msecs
       Print count deltas every N milliseconds (minimum: 10ms) The
       overhead percentage could be high in some cases, for instance
       with small, sub 100ms intervals. Use with caution. example: perf
       stat -I 1000 -e cycles -a sleep 5

  For best results it is usually a good idea to use it with interval
   mode like -I 1000, as the bottleneck of workloads can change often.

还有机器可读形式的导入结果,-I第一个字段是datetime:

  

使用-x,perf stat能够输出不完全CSV格式的输出...可选的usec时间戳,以秒为单位(使用-I xxx)

vmstat,systat家庭工具iostatmpstat等定期打印是性能值-I 1000(每秒),例如系统范围(添加 - A来分隔cpu计数器):

  perf stat -a -I 1000

该选项在builtin-stat.c http://lxr.free-electrons.com/source/tools/perf/builtin-stat.c?v=4.8 __run_perf_stat函数

中实现
531 static int __run_perf_stat(int argc, const char **argv)
532 {
533         int interval = stat_config.interval;

对于带有一些程序参数(perf stat -I 1000)的forks=1,例如perf stat -I 1000 sleep 10,有间隔循环(ts是转换为struct timespec的毫秒间隔) :

639                 enable_counters();
641                 if (interval) {
642                         while (!waitpid(child_pid, &status, WNOHANG)) {
643                                 nanosleep(&ts, NULL);
644                                 process_interval();
645                         }
646                 }
666         disable_counters();

对于系统范围的硬件性能监视器计数的变体,forks=0还有其他间隔循环

658                 enable_counters();
659                 while (!done) {
660                         nanosleep(&ts, NULL);
661                         if (interval)
662                                 process_interval();
663                 }
666         disable_counters();
来自同一文件的

process_interval() http://lxr.free-electrons.com/source/tools/perf/builtin-stat.c?v=4.8#L347使用read_counters();循环遍历事件列表并调用read_counter() loops over所有已知线程和所有cpus并启动实际阅读功能:

306         for (thread = 0; thread < nthreads; thread++) {
307                 for (cpu = 0; cpu < ncpus; cpu++) {
...
310                         count = perf_counts(counter->counts, cpu, thread);
311                         if (perf_evsel__read(counter, cpu, thread, count))
312                                 return -1;
当程序仍在运行时,

perf_evsel__read是真正的计数器读取:

1207 int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread,
1208                      struct perf_counts_values *count)
1209 {
1210         memset(count, 0, sizeof(*count));
1211 
1212         if (FD(evsel, cpu, thread) < 0)
1213                 return -EINVAL;
1214 
1215         if (readn(FD(evsel, cpu, thread), count, sizeof(*count)) < 0)
1216                 return -errno;
1217 
1218         return 0;
1219 }