2017-09-27 334 views
1

我很想知道perf stat中用来计算原始数据的公式。perf stat中的公式

perf stat -e task-clock,cycles,instructions,cache-references,cache-misses ./myapp 

    1080267.226401  task-clock (msec)   # 19.062 CPUs utilized   
1,592,123,216,789  cycles     # 1.474 GHz      (50.00%) 
    871,190,006,655  instructions    # 0.55 insn per cycle   (75.00%) 
    3,697,548,810  cache-references   # 3.423 M/sec     (75.00%) 
     459,457,321  cache-misses    # 12.426 % of all cache refs  (75.00%) 

在这种情况下,您如何计算缓存参考的M /秒?

+2

不知道我是否正确地得到了问题。这只是'cache-references' /'任务时钟',不是吗? – Zulan

+0

@卓兰杜!当然,这是......我想这会更复杂 – Manolete

+1

不用担心;-)。复杂的部分是'(75%)'表示的反复用,但隐藏在幕后。 – Zulan

回答

1

的公式似乎不是在builtin-stat.c(其中default event sets for perf stat are defined)实现,但他们可能计算(and averaged与STDDEV)在perf_stat__print_shadow_stats()(和一些统计数据被收集到阵列中perf_stat__update_shadow_stats()):

http://elixir.free-electrons.com/linux/v4.13.4/source/tools/perf/util/stat-shadow.c#L626

当HW_INSTRUCTIONS计数时: “每个时钟的指令”= HW_INSTRUCTIONS/HW_CPU_CYCLES; “每个指令停顿周期”= HW_STALLED_CYCLES_FRONTEND/HW_INSTRUCTIONS

if (perf_evsel__match(evsel, HARDWARE, HW_INSTRUCTIONS)) { 
    total = avg_stats(&runtime_cycles_stats[ctx][cpu]); 
    if (total) { 
     ratio = avg/total; 
     print_metric(ctxp, NULL, "%7.2f ", 
       "insn per cycle", ratio); 
    } else { 
     print_metric(ctxp, NULL, NULL, "insn per cycle", 0); 
    } 

科未命中从print_branch_misses作为HW_BRANCH_MISSES/HW_BRANCH_INSTRUCTIONS

有在perf_stat__print_shadow_stats()几个高速缓存未命中率的计算太像HW_CACHE_MISSES/HW_CACHE_REFERENCES和一些更详细的(perf stat -d模式)。

停滞百分比are computed作为HW_STALLED_CYCLES_FRONTEND/HW_CPU_CYCLES和HW_STALLED_CYCLES_BACKEND/HW_CPU_CYCLES

GHz的计算为HW_CPU_CYCLES/runtime_nsecs_stats,其中runtime_nsecs_stats从任何的软件事件task-clockcpu-clock(SW_TASK_CLOCK & SW_CPU_CLOCK,We still know no exact difference between them two 2010年以来LKML和更新2014在SO)

if (perf_evsel__match(counter, SOFTWARE, SW_TASK_CLOCK) || 
    perf_evsel__match(counter, SOFTWARE, SW_CPU_CLOCK)) 
    update_stats(&runtime_nsecs_stats[cpu], count[0]); 

还有several formulas for transactionsperf stat -T模式)。

"CPU utilized" is fromtask-clockcpu-clock/walltime_nsecs_stats,其中walltime通过使用时钟从壁the perf stat itself (in userspace计算(天文时间):

static inline unsigned long long rdclock(void) 
{ 
    struct timespec ts; 

    clock_gettime(CLOCK_MONOTONIC, &ts); 
    return ts.tv_sec * 1000000000ULL + ts.tv_nsec; 
} 

... 

static int __run_perf_stat(int argc, const char **argv) 
{  
... 
    /* 
    * Enable counters and exec the command: 
    */ 
    t0 = rdclock(); 
    clock_gettime(CLOCK_MONOTONIC, &ref_time); 
    if (forks) { 
     .... 
    } 
    t1 = rdclock(); 

    update_stats(&walltime_nsecs_stats, t1 - t0); 

还有some estimations从顶向下的方法(Tuning Applications Using a Top-down Microarchitecture Analysis MethodSoftware Optimizations Become Simple with Top-Down Analysis .. Name Skylake, IDF2015, #22 Gregg's Methodology List。由Andi Kleen在2016年描述https://lwn.net/Articles/688335/“将自上而下的指标添加到perf stat”(perf stat --topdown -I 1000 cmd模式)。

A最后,如果当前打印事件没有确切的公式,则存在通用的“%c/sec”(K/sec或M/sec)度量标准:http://elixir.free-electrons.com/linux/v4.13.4/source/tools/perf/util/stat-shadow.c#L845除以运行时间nsec(任务时钟或cpu时钟事件,如果它们出现在perf stat事件集中)

} else if (runtime_nsecs_stats[cpu].n != 0) { 
    char unit = 'M'; 
    char unit_buf[10]; 

    total = avg_stats(&runtime_nsecs_stats[cpu]); 

    if (total) 
     ratio = 1000.0 * avg/total; 
    if (ratio < 0.001) { 
     ratio *= 1000; 
     unit = 'K'; 
    } 
    snprintf(unit_buf, sizeof(unit_buf), "%c/sec", unit); 
    print_metric(ctxp, NULL, "%8.3f", unit_buf, ratio); 
}