【问题标题】:Use linux perf utility to report counters every second like vmstat使用 linux perf 实用程序每秒报告一次计数器,如 vmstat
【发布时间】:2017-03-24 02:31:00
【问题描述】:

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

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

是否存在perf 模式以每秒(每 3、5、10 秒)打印系统范围或每个 CPU 的总计数摘要,就像在 vmstat 和 sysstat-family 工具中打印的一样(@ 987654332@、mpstatsar -n DEV... 就像在http://techblog.netflix.com/2015/11/linux-performance-analysis-in-60s.html 中列出的一样?例如,使用周期和指令计数器,我将获得系统(或每个 CPU)每秒的平均 IPC。

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

【问题讨论】:

    标签: linux performancecounter perf


    【解决方案1】:

    -I Nperf stat 选项“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第一个字段是日期时间:

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

    vmstat, sysstat-family toolsiostat, mpstat, etc 定期打印是 perf stat 的-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;
    

    对于带有一些程序参数(forks=1)的perf stat -I 1000,例如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 所有已知线程和所有 cpu 并启动实际读取功能:

    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 }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多