6

I'm profiling a program on Linux, using the "time" command. The problem is it's output is not very statistically relevant as it does only run the program once. Is there a tool or a way to get an average of several "time" runs? Possibly aswel together with statistical information such as deviation?

4

4 回答 4

8

这是我编写的一个脚本,用于执行与您正在寻找的类似的操作。它运行提供的命令 10 次,将真实、用户 CPU 和系统 CPU 时间记录到文件中,并在每个命令输出后回显 tham。然后,它使用 awk 提供文件中 3 列中每一列的平均值,但(还)不包括标准偏差。

#!/bin/bash

rm -f /tmp/mtime.$$

for x in {1..10}
do
  /usr/bin/time -f "real %e user %U sys %S" -a -o /tmp/mtime.$$ $@
  tail -1 /tmp/mtime.$$
done

awk '{ et += $2; ut += $4; st += $6; count++ } END {  printf "Average:\nreal %.3f user %.3f sys %.3f\n", et/count, ut/count, st/count }' /tmp/mtime.$$
于 2015-10-29T18:40:10.613 回答
1

使用超精细

例如:

hyperfine 'sleep 0.3'

sleep 0.3将多次运行该命令,然后输出如下内容:

hyperfine 'sleep 0.3'
Benchmark #1: sleep 0.3
  Time (mean ± σ):     306.7 ms ±   3.0 ms    [User: 2.8 ms, System: 3.5 ms]
  Range (min … max):   301.0 ms … 310.9 ms    10 runs
于 2021-07-25T17:39:03.913 回答
1

perf stat-r使用( ) 选项为您执行此操作-repeat=<n>,具有平均值和方差。

例如,使用一个短循环awk来模拟一些工作,足够短以至于 CPU 频率上升和其他启动开销可能是一个因素(性能评估的惯用方式?),尽管我的 CPU 似乎很快就上升到 3.9GHz,平均3.82 GHz。

$ perf stat -r5 awk 'BEGIN{for(i=0;i<1000000;i++){}}'

 Performance counter stats for 'awk BEGIN{for(i=0;i<1000000;i++){}}' (5 runs):

             37.90 msec task-clock                #    0.968 CPUs utilized            ( +-  2.18% )
                 1      context-switches          #   31.662 /sec                     ( +-100.00% )
                 0      cpu-migrations            #    0.000 /sec                   
               181      page-faults               #    4.776 K/sec                    ( +-  0.39% )
       144,802,875      cycles                    #    3.821 GHz                      ( +-  0.23% )
       343,697,186      instructions              #    2.37  insn per cycle           ( +-  0.05% )
        93,854,279      branches                  #    2.476 G/sec                    ( +-  0.04% )
            29,245      branch-misses             #    0.03% of all branches          ( +- 12.79% )

           0.03917 +- 0.00182 seconds time elapsed  ( +-  4.63% )

(向右滚动查看差异。)

taskset -c3 perf stat ...如果您有一个单线程任务并且想要最小化上下文切换,您可以使用将任务固定到特定核心(在这种情况下为#3)。

默认情况下,perf stat使用硬件性能计数器来分析指令、核心时钟周期(与现代 CPU 上的时间不同)和分支未命中等内容。这具有相当低的开销,尤其是在计数器处于“计数”模式而不是perf record导致中断以统计事件的热点时。

您可以使用-e task-clock该事件而不使用硬件性能计数器。(或者,如果您的系统在 VM 中,或者您没有更改默认值/proc/sys/kernel/perf_event_paranoid,则 perf 可能无法要求内核进行任何编程。)

有关更多信息perf,请参阅


对于打印输出的程序,它看起来像这样:

$ perf stat -r5 echo hello
hello
hello
hello
hello
hello

 Performance counter stats for 'echo hello' (5 runs):

              0.27 msec task-clock                #    0.302 CPUs utilized            ( +-  4.51% )
...
          0.000890 +- 0.000411 seconds time elapsed  ( +- 46.21% )

对于单次运行,(默认为 no -r), perf stat 将显示经过的时间,以及 user / sys. 但-r出于某种原因,并不平均这些。

于 2021-07-25T21:11:40.567 回答
-1

就像上面提到的评论者一样,听起来您可能想使用循环多次运行您的程序,以获取更多数据点。您可以使用带有 -o 选项的 time 命令将 time 命令的结果输出到文本文件,如下所示: time -o output.txt myprog

于 2013-07-11T20:49:34.377 回答