Les formules sont Semble ne pas être mis en œuvre dans le builtin-stat.c
(où default event sets for perf stat
are defined), mais ils sont probablement calculés (and averaged avec stddev) dans perf_stat__print_shadow_stats()
(et quelques statistiques sont collectées dans des tableaux en perf_stat__update_shadow_stats()
):
http://elixir.free-electrons.com/linux/v4.13.4/source/tools/perf/util/stat-shadow.c#L626
Lorsque HW_INSTRUCTIONS est comptabilisé: "Instructions par horloge" = HW_INSTRUCTIONS/HW_CPU_CYCLES; "cycles au point mort par instruction" = 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);
}
misses Branch sont de print_branch_misses
comme HW_BRANCH_MISSES/HW_BRANCH_INSTRUCTIONS
Il existe plusieurs calculs de ratio de défaut de cache dans perf_stat__print_shadow_stats()
aussi comme HW_CACHE_MISSES/HW_CACHE_REFERENCES et certains (perf stat -d
plus détaillée mode).
Percents DU RETARD are computed comme HW_STALLED_CYCLES_FRONTEND/HW_CPU_CYCLES et HW_STALLED_CYCLES_BACKEND/HW_CPU_CYCLES
GHz est calculé comme HW_CPU_CYCLES/runtime_nsecs_stats, où runtime_nsecs_stats
a été mis à jour de l'un des événements logiciels task-clock
ou cpu-clock
(SW_TASK_CLOCK & SW_CPU_CLOCK, We still know no exact difference between them two depuis 2010 dans LKML et 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]);
Il y a aussi several formulas for transactions (mode perf stat -T
).
"CPU utilized" is fromtask-clock
ou cpu-clock
/walltime_nsecs_stats, où walltime est calculé par the perf stat itself (in userspace horloge à l'aide du mur (temps astronomique,):
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);
Il y a aussi some estimations de la méthode descendante (Tuning Applications Using a Top-down Microarchitecture Analysis Method, Software Optimizations Become Simple with Top-Down Analysis .. Name Skylake, IDF2015, # 22 en Gregg's Methodology List Décrit en 2016 par Andi Kleen https://lwn.net/Articles/688335/ "Ajouter des statistiques descendantes à la statistique perf" (mode perf stat --topdown -I 1000 cmd
)
A Enfin, s'il n'y avait pas de formule exacte pour l'événement en cours d'impression, il existe une métrique universelle "% c/sec" (K/sec ou M/sec): http://elixir.free-electrons.com/linux/v4.13.4/source/tools/perf/util/stat-shadow.c#L845 Tout ce qui est divisé par runtime nsec (horloge de tâche ou événements cpu-clock , s'ils étaient présents dans l'ensemble d'événements 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);
}
Je ne suis pas sûr d'avoir la bonne question. C'est juste 'cache-references' /' task-clock', n'est-ce pas? – Zulan
@Zulan Duh! Bien sûr, c'est ... Je pensais que ce serait beaucoup plus compliqué – Manolete
Pas de soucis ;-). La partie compliquée est le multiplexage du compteur indiqué par '(75%)', mais caché derrière le rideau. – Zulan