aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/stat-shadow.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/stat-shadow.c')
-rw-r--r--tools/perf/util/stat-shadow.c225
1 files changed, 130 insertions, 95 deletions
diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
index 6ac03146889d..b33ffb2af2cf 100644
--- a/tools/perf/util/stat-shadow.c
+++ b/tools/perf/util/stat-shadow.c
@@ -2,6 +2,7 @@
2#include "evsel.h" 2#include "evsel.h"
3#include "stat.h" 3#include "stat.h"
4#include "color.h" 4#include "color.h"
5#include "pmu.h"
5 6
6enum { 7enum {
7 CTX_BIT_USER = 1 << 0, 8 CTX_BIT_USER = 1 << 0,
@@ -14,6 +15,13 @@ enum {
14 15
15#define NUM_CTX CTX_BIT_MAX 16#define NUM_CTX CTX_BIT_MAX
16 17
18/*
19 * AGGR_GLOBAL: Use CPU 0
20 * AGGR_SOCKET: Use first CPU of socket
21 * AGGR_CORE: Use first CPU of core
22 * AGGR_NONE: Use matching CPU
23 * AGGR_THREAD: Not supported?
24 */
17static struct stats runtime_nsecs_stats[MAX_NR_CPUS]; 25static struct stats runtime_nsecs_stats[MAX_NR_CPUS];
18static struct stats runtime_cycles_stats[NUM_CTX][MAX_NR_CPUS]; 26static struct stats runtime_cycles_stats[NUM_CTX][MAX_NR_CPUS];
19static struct stats runtime_stalled_cycles_front_stats[NUM_CTX][MAX_NR_CPUS]; 27static struct stats runtime_stalled_cycles_front_stats[NUM_CTX][MAX_NR_CPUS];
@@ -28,9 +36,15 @@ static struct stats runtime_dtlb_cache_stats[NUM_CTX][MAX_NR_CPUS];
28static struct stats runtime_cycles_in_tx_stats[NUM_CTX][MAX_NR_CPUS]; 36static struct stats runtime_cycles_in_tx_stats[NUM_CTX][MAX_NR_CPUS];
29static struct stats runtime_transaction_stats[NUM_CTX][MAX_NR_CPUS]; 37static struct stats runtime_transaction_stats[NUM_CTX][MAX_NR_CPUS];
30static struct stats runtime_elision_stats[NUM_CTX][MAX_NR_CPUS]; 38static struct stats runtime_elision_stats[NUM_CTX][MAX_NR_CPUS];
39static bool have_frontend_stalled;
31 40
32struct stats walltime_nsecs_stats; 41struct stats walltime_nsecs_stats;
33 42
43void perf_stat__init_shadow_stats(void)
44{
45 have_frontend_stalled = pmu_have_event("cpu", "stalled-cycles-frontend");
46}
47
34static int evsel_context(struct perf_evsel *evsel) 48static int evsel_context(struct perf_evsel *evsel)
35{ 49{
36 int ctx = 0; 50 int ctx = 0;
@@ -137,9 +151,10 @@ static const char *get_ratio_color(enum grc_type type, double ratio)
137 return color; 151 return color;
138} 152}
139 153
140static void print_stalled_cycles_frontend(FILE *out, int cpu, 154static void print_stalled_cycles_frontend(int cpu,
141 struct perf_evsel *evsel 155 struct perf_evsel *evsel
142 __maybe_unused, double avg) 156 __maybe_unused, double avg,
157 struct perf_stat_output_ctx *out)
143{ 158{
144 double total, ratio = 0.0; 159 double total, ratio = 0.0;
145 const char *color; 160 const char *color;
@@ -152,14 +167,17 @@ static void print_stalled_cycles_frontend(FILE *out, int cpu,
152 167
153 color = get_ratio_color(GRC_STALLED_CYCLES_FE, ratio); 168 color = get_ratio_color(GRC_STALLED_CYCLES_FE, ratio);
154 169
155 fprintf(out, " # "); 170 if (ratio)
156 color_fprintf(out, color, "%6.2f%%", ratio); 171 out->print_metric(out->ctx, color, "%7.2f%%", "frontend cycles idle",
157 fprintf(out, " frontend cycles idle "); 172 ratio);
173 else
174 out->print_metric(out->ctx, NULL, NULL, "frontend cycles idle", 0);
158} 175}
159 176
160static void print_stalled_cycles_backend(FILE *out, int cpu, 177static void print_stalled_cycles_backend(int cpu,
161 struct perf_evsel *evsel 178 struct perf_evsel *evsel
162 __maybe_unused, double avg) 179 __maybe_unused, double avg,
180 struct perf_stat_output_ctx *out)
163{ 181{
164 double total, ratio = 0.0; 182 double total, ratio = 0.0;
165 const char *color; 183 const char *color;
@@ -172,14 +190,13 @@ static void print_stalled_cycles_backend(FILE *out, int cpu,
172 190
173 color = get_ratio_color(GRC_STALLED_CYCLES_BE, ratio); 191 color = get_ratio_color(GRC_STALLED_CYCLES_BE, ratio);
174 192
175 fprintf(out, " # "); 193 out->print_metric(out->ctx, color, "%6.2f%%", "backend cycles idle", ratio);
176 color_fprintf(out, color, "%6.2f%%", ratio);
177 fprintf(out, " backend cycles idle ");
178} 194}
179 195
180static void print_branch_misses(FILE *out, int cpu, 196static void print_branch_misses(int cpu,
181 struct perf_evsel *evsel __maybe_unused, 197 struct perf_evsel *evsel __maybe_unused,
182 double avg) 198 double avg,
199 struct perf_stat_output_ctx *out)
183{ 200{
184 double total, ratio = 0.0; 201 double total, ratio = 0.0;
185 const char *color; 202 const char *color;
@@ -192,14 +209,13 @@ static void print_branch_misses(FILE *out, int cpu,
192 209
193 color = get_ratio_color(GRC_CACHE_MISSES, ratio); 210 color = get_ratio_color(GRC_CACHE_MISSES, ratio);
194 211
195 fprintf(out, " # "); 212 out->print_metric(out->ctx, color, "%7.2f%%", "of all branches", ratio);
196 color_fprintf(out, color, "%6.2f%%", ratio);
197 fprintf(out, " of all branches ");
198} 213}
199 214
200static void print_l1_dcache_misses(FILE *out, int cpu, 215static void print_l1_dcache_misses(int cpu,
201 struct perf_evsel *evsel __maybe_unused, 216 struct perf_evsel *evsel __maybe_unused,
202 double avg) 217 double avg,
218 struct perf_stat_output_ctx *out)
203{ 219{
204 double total, ratio = 0.0; 220 double total, ratio = 0.0;
205 const char *color; 221 const char *color;
@@ -212,14 +228,13 @@ static void print_l1_dcache_misses(FILE *out, int cpu,
212 228
213 color = get_ratio_color(GRC_CACHE_MISSES, ratio); 229 color = get_ratio_color(GRC_CACHE_MISSES, ratio);
214 230
215 fprintf(out, " # "); 231 out->print_metric(out->ctx, color, "%7.2f%%", "of all L1-dcache hits", ratio);
216 color_fprintf(out, color, "%6.2f%%", ratio);
217 fprintf(out, " of all L1-dcache hits ");
218} 232}
219 233
220static void print_l1_icache_misses(FILE *out, int cpu, 234static void print_l1_icache_misses(int cpu,
221 struct perf_evsel *evsel __maybe_unused, 235 struct perf_evsel *evsel __maybe_unused,
222 double avg) 236 double avg,
237 struct perf_stat_output_ctx *out)
223{ 238{
224 double total, ratio = 0.0; 239 double total, ratio = 0.0;
225 const char *color; 240 const char *color;
@@ -231,15 +246,13 @@ static void print_l1_icache_misses(FILE *out, int cpu,
231 ratio = avg / total * 100.0; 246 ratio = avg / total * 100.0;
232 247
233 color = get_ratio_color(GRC_CACHE_MISSES, ratio); 248 color = get_ratio_color(GRC_CACHE_MISSES, ratio);
234 249 out->print_metric(out->ctx, color, "%7.2f%%", "of all L1-icache hits", ratio);
235 fprintf(out, " # ");
236 color_fprintf(out, color, "%6.2f%%", ratio);
237 fprintf(out, " of all L1-icache hits ");
238} 250}
239 251
240static void print_dtlb_cache_misses(FILE *out, int cpu, 252static void print_dtlb_cache_misses(int cpu,
241 struct perf_evsel *evsel __maybe_unused, 253 struct perf_evsel *evsel __maybe_unused,
242 double avg) 254 double avg,
255 struct perf_stat_output_ctx *out)
243{ 256{
244 double total, ratio = 0.0; 257 double total, ratio = 0.0;
245 const char *color; 258 const char *color;
@@ -251,15 +264,13 @@ static void print_dtlb_cache_misses(FILE *out, int cpu,
251 ratio = avg / total * 100.0; 264 ratio = avg / total * 100.0;
252 265
253 color = get_ratio_color(GRC_CACHE_MISSES, ratio); 266 color = get_ratio_color(GRC_CACHE_MISSES, ratio);
254 267 out->print_metric(out->ctx, color, "%7.2f%%", "of all dTLB cache hits", ratio);
255 fprintf(out, " # ");
256 color_fprintf(out, color, "%6.2f%%", ratio);
257 fprintf(out, " of all dTLB cache hits ");
258} 268}
259 269
260static void print_itlb_cache_misses(FILE *out, int cpu, 270static void print_itlb_cache_misses(int cpu,
261 struct perf_evsel *evsel __maybe_unused, 271 struct perf_evsel *evsel __maybe_unused,
262 double avg) 272 double avg,
273 struct perf_stat_output_ctx *out)
263{ 274{
264 double total, ratio = 0.0; 275 double total, ratio = 0.0;
265 const char *color; 276 const char *color;
@@ -271,15 +282,13 @@ static void print_itlb_cache_misses(FILE *out, int cpu,
271 ratio = avg / total * 100.0; 282 ratio = avg / total * 100.0;
272 283
273 color = get_ratio_color(GRC_CACHE_MISSES, ratio); 284 color = get_ratio_color(GRC_CACHE_MISSES, ratio);
274 285 out->print_metric(out->ctx, color, "%7.2f%%", "of all iTLB cache hits", ratio);
275 fprintf(out, " # ");
276 color_fprintf(out, color, "%6.2f%%", ratio);
277 fprintf(out, " of all iTLB cache hits ");
278} 286}
279 287
280static void print_ll_cache_misses(FILE *out, int cpu, 288static void print_ll_cache_misses(int cpu,
281 struct perf_evsel *evsel __maybe_unused, 289 struct perf_evsel *evsel __maybe_unused,
282 double avg) 290 double avg,
291 struct perf_stat_output_ctx *out)
283{ 292{
284 double total, ratio = 0.0; 293 double total, ratio = 0.0;
285 const char *color; 294 const char *color;
@@ -291,15 +300,15 @@ static void print_ll_cache_misses(FILE *out, int cpu,
291 ratio = avg / total * 100.0; 300 ratio = avg / total * 100.0;
292 301
293 color = get_ratio_color(GRC_CACHE_MISSES, ratio); 302 color = get_ratio_color(GRC_CACHE_MISSES, ratio);
294 303 out->print_metric(out->ctx, color, "%7.2f%%", "of all LL-cache hits", ratio);
295 fprintf(out, " # ");
296 color_fprintf(out, color, "%6.2f%%", ratio);
297 fprintf(out, " of all LL-cache hits ");
298} 304}
299 305
300void perf_stat__print_shadow_stats(FILE *out, struct perf_evsel *evsel, 306void perf_stat__print_shadow_stats(struct perf_evsel *evsel,
301 double avg, int cpu, enum aggr_mode aggr) 307 double avg, int cpu,
308 struct perf_stat_output_ctx *out)
302{ 309{
310 void *ctxp = out->ctx;
311 print_metric_t print_metric = out->print_metric;
303 double total, ratio = 0.0, total2; 312 double total, ratio = 0.0, total2;
304 int ctx = evsel_context(evsel); 313 int ctx = evsel_context(evsel);
305 314
@@ -307,119 +316,145 @@ void perf_stat__print_shadow_stats(FILE *out, struct perf_evsel *evsel,
307 total = avg_stats(&runtime_cycles_stats[ctx][cpu]); 316 total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
308 if (total) { 317 if (total) {
309 ratio = avg / total; 318 ratio = avg / total;
310 fprintf(out, " # %5.2f insns per cycle ", ratio); 319 print_metric(ctxp, NULL, "%7.2f ",
320 "insn per cycle", ratio);
311 } else { 321 } else {
312 fprintf(out, " "); 322 print_metric(ctxp, NULL, NULL, "insn per cycle", 0);
313 } 323 }
314 total = avg_stats(&runtime_stalled_cycles_front_stats[ctx][cpu]); 324 total = avg_stats(&runtime_stalled_cycles_front_stats[ctx][cpu]);
315 total = max(total, avg_stats(&runtime_stalled_cycles_back_stats[ctx][cpu])); 325 total = max(total, avg_stats(&runtime_stalled_cycles_back_stats[ctx][cpu]));
316 326
317 if (total && avg) { 327 if (total && avg) {
328 out->new_line(ctxp);
318 ratio = total / avg; 329 ratio = total / avg;
319 fprintf(out, "\n"); 330 print_metric(ctxp, NULL, "%7.2f ",
320 if (aggr == AGGR_NONE) 331 "stalled cycles per insn",
321 fprintf(out, " "); 332 ratio);
322 fprintf(out, " # %5.2f stalled cycles per insn", ratio); 333 } else if (have_frontend_stalled) {
334 print_metric(ctxp, NULL, NULL,
335 "stalled cycles per insn", 0);
323 } 336 }
324 337 } else if (perf_evsel__match(evsel, HARDWARE, HW_BRANCH_MISSES)) {
325 } else if (perf_evsel__match(evsel, HARDWARE, HW_BRANCH_MISSES) && 338 if (runtime_branches_stats[ctx][cpu].n != 0)
326 runtime_branches_stats[ctx][cpu].n != 0) { 339 print_branch_misses(cpu, evsel, avg, out);
327 print_branch_misses(out, cpu, evsel, avg); 340 else
341 print_metric(ctxp, NULL, NULL, "of all branches", 0);
328 } else if ( 342 } else if (
329 evsel->attr.type == PERF_TYPE_HW_CACHE && 343 evsel->attr.type == PERF_TYPE_HW_CACHE &&
330 evsel->attr.config == ( PERF_COUNT_HW_CACHE_L1D | 344 evsel->attr.config == ( PERF_COUNT_HW_CACHE_L1D |
331 ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | 345 ((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
332 ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) && 346 ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16))) {
333 runtime_l1_dcache_stats[ctx][cpu].n != 0) { 347 if (runtime_l1_dcache_stats[ctx][cpu].n != 0)
334 print_l1_dcache_misses(out, cpu, evsel, avg); 348 print_l1_dcache_misses(cpu, evsel, avg, out);
349 else
350 print_metric(ctxp, NULL, NULL, "of all L1-dcache hits", 0);
335 } else if ( 351 } else if (
336 evsel->attr.type == PERF_TYPE_HW_CACHE && 352 evsel->attr.type == PERF_TYPE_HW_CACHE &&
337 evsel->attr.config == ( PERF_COUNT_HW_CACHE_L1I | 353 evsel->attr.config == ( PERF_COUNT_HW_CACHE_L1I |
338 ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | 354 ((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
339 ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) && 355 ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16))) {
340 runtime_l1_icache_stats[ctx][cpu].n != 0) { 356 if (runtime_l1_icache_stats[ctx][cpu].n != 0)
341 print_l1_icache_misses(out, cpu, evsel, avg); 357 print_l1_icache_misses(cpu, evsel, avg, out);
358 else
359 print_metric(ctxp, NULL, NULL, "of all L1-icache hits", 0);
342 } else if ( 360 } else if (
343 evsel->attr.type == PERF_TYPE_HW_CACHE && 361 evsel->attr.type == PERF_TYPE_HW_CACHE &&
344 evsel->attr.config == ( PERF_COUNT_HW_CACHE_DTLB | 362 evsel->attr.config == ( PERF_COUNT_HW_CACHE_DTLB |
345 ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | 363 ((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
346 ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) && 364 ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16))) {
347 runtime_dtlb_cache_stats[ctx][cpu].n != 0) { 365 if (runtime_dtlb_cache_stats[ctx][cpu].n != 0)
348 print_dtlb_cache_misses(out, cpu, evsel, avg); 366 print_dtlb_cache_misses(cpu, evsel, avg, out);
367 else
368 print_metric(ctxp, NULL, NULL, "of all dTLB cache hits", 0);
349 } else if ( 369 } else if (
350 evsel->attr.type == PERF_TYPE_HW_CACHE && 370 evsel->attr.type == PERF_TYPE_HW_CACHE &&
351 evsel->attr.config == ( PERF_COUNT_HW_CACHE_ITLB | 371 evsel->attr.config == ( PERF_COUNT_HW_CACHE_ITLB |
352 ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | 372 ((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
353 ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) && 373 ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16))) {
354 runtime_itlb_cache_stats[ctx][cpu].n != 0) { 374 if (runtime_itlb_cache_stats[ctx][cpu].n != 0)
355 print_itlb_cache_misses(out, cpu, evsel, avg); 375 print_itlb_cache_misses(cpu, evsel, avg, out);
376 else
377 print_metric(ctxp, NULL, NULL, "of all iTLB cache hits", 0);
356 } else if ( 378 } else if (
357 evsel->attr.type == PERF_TYPE_HW_CACHE && 379 evsel->attr.type == PERF_TYPE_HW_CACHE &&
358 evsel->attr.config == ( PERF_COUNT_HW_CACHE_LL | 380 evsel->attr.config == ( PERF_COUNT_HW_CACHE_LL |
359 ((PERF_COUNT_HW_CACHE_OP_READ) << 8) | 381 ((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
360 ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16)) && 382 ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16))) {
361 runtime_ll_cache_stats[ctx][cpu].n != 0) { 383 if (runtime_ll_cache_stats[ctx][cpu].n != 0)
362 print_ll_cache_misses(out, cpu, evsel, avg); 384 print_ll_cache_misses(cpu, evsel, avg, out);
363 } else if (perf_evsel__match(evsel, HARDWARE, HW_CACHE_MISSES) && 385 else
364 runtime_cacherefs_stats[ctx][cpu].n != 0) { 386 print_metric(ctxp, NULL, NULL, "of all LL-cache hits", 0);
387 } else if (perf_evsel__match(evsel, HARDWARE, HW_CACHE_MISSES)) {
365 total = avg_stats(&runtime_cacherefs_stats[ctx][cpu]); 388 total = avg_stats(&runtime_cacherefs_stats[ctx][cpu]);
366 389
367 if (total) 390 if (total)
368 ratio = avg * 100 / total; 391 ratio = avg * 100 / total;
369 392
370 fprintf(out, " # %8.3f %% of all cache refs ", ratio); 393 if (runtime_cacherefs_stats[ctx][cpu].n != 0)
371 394 print_metric(ctxp, NULL, "%8.3f %%",
395 "of all cache refs", ratio);
396 else
397 print_metric(ctxp, NULL, NULL, "of all cache refs", 0);
372 } else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_FRONTEND)) { 398 } else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_FRONTEND)) {
373 print_stalled_cycles_frontend(out, cpu, evsel, avg); 399 print_stalled_cycles_frontend(cpu, evsel, avg, out);
374 } else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_BACKEND)) { 400 } else if (perf_evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_BACKEND)) {
375 print_stalled_cycles_backend(out, cpu, evsel, avg); 401 print_stalled_cycles_backend(cpu, evsel, avg, out);
376 } else if (perf_evsel__match(evsel, HARDWARE, HW_CPU_CYCLES)) { 402 } else if (perf_evsel__match(evsel, HARDWARE, HW_CPU_CYCLES)) {
377 total = avg_stats(&runtime_nsecs_stats[cpu]); 403 total = avg_stats(&runtime_nsecs_stats[cpu]);
378 404
379 if (total) { 405 if (total) {
380 ratio = avg / total; 406 ratio = avg / total;
381 fprintf(out, " # %8.3f GHz ", ratio); 407 print_metric(ctxp, NULL, "%8.3f", "GHz", ratio);
382 } else { 408 } else {
383 fprintf(out, " "); 409 print_metric(ctxp, NULL, NULL, "Ghz", 0);
384 } 410 }
385 } else if (perf_stat_evsel__is(evsel, CYCLES_IN_TX)) { 411 } else if (perf_stat_evsel__is(evsel, CYCLES_IN_TX)) {
386 total = avg_stats(&runtime_cycles_stats[ctx][cpu]); 412 total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
387 if (total) 413 if (total)
388 fprintf(out, 414 print_metric(ctxp, NULL,
389 " # %5.2f%% transactional cycles ", 415 "%7.2f%%", "transactional cycles",
390 100.0 * (avg / total)); 416 100.0 * (avg / total));
417 else
418 print_metric(ctxp, NULL, NULL, "transactional cycles",
419 0);
391 } else if (perf_stat_evsel__is(evsel, CYCLES_IN_TX_CP)) { 420 } else if (perf_stat_evsel__is(evsel, CYCLES_IN_TX_CP)) {
392 total = avg_stats(&runtime_cycles_stats[ctx][cpu]); 421 total = avg_stats(&runtime_cycles_stats[ctx][cpu]);
393 total2 = avg_stats(&runtime_cycles_in_tx_stats[ctx][cpu]); 422 total2 = avg_stats(&runtime_cycles_in_tx_stats[ctx][cpu]);
394 if (total2 < avg) 423 if (total2 < avg)
395 total2 = avg; 424 total2 = avg;
396 if (total) 425 if (total)
397 fprintf(out, 426 print_metric(ctxp, NULL, "%7.2f%%", "aborted cycles",
398 " # %5.2f%% aborted cycles ",
399 100.0 * ((total2-avg) / total)); 427 100.0 * ((total2-avg) / total));
400 } else if (perf_stat_evsel__is(evsel, TRANSACTION_START) && 428 else
401 runtime_cycles_in_tx_stats[ctx][cpu].n != 0) { 429 print_metric(ctxp, NULL, NULL, "aborted cycles", 0);
430 } else if (perf_stat_evsel__is(evsel, TRANSACTION_START)) {
402 total = avg_stats(&runtime_cycles_in_tx_stats[ctx][cpu]); 431 total = avg_stats(&runtime_cycles_in_tx_stats[ctx][cpu]);
403 432
404 if (avg) 433 if (avg)
405 ratio = total / avg; 434 ratio = total / avg;
406 435
407 fprintf(out, " # %8.0f cycles / transaction ", ratio); 436 if (runtime_cycles_in_tx_stats[ctx][cpu].n != 0)
408 } else if (perf_stat_evsel__is(evsel, ELISION_START) && 437 print_metric(ctxp, NULL, "%8.0f",
409 runtime_cycles_in_tx_stats[ctx][cpu].n != 0) { 438 "cycles / transaction", ratio);
439 else
440 print_metric(ctxp, NULL, NULL, "cycles / transaction",
441 0);
442 } else if (perf_stat_evsel__is(evsel, ELISION_START)) {
410 total = avg_stats(&runtime_cycles_in_tx_stats[ctx][cpu]); 443 total = avg_stats(&runtime_cycles_in_tx_stats[ctx][cpu]);
411 444
412 if (avg) 445 if (avg)
413 ratio = total / avg; 446 ratio = total / avg;
414 447
415 fprintf(out, " # %8.0f cycles / elision ", ratio); 448 print_metric(ctxp, NULL, "%8.0f", "cycles / elision", ratio);
416 } else if (perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK)) { 449 } else if (perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK)) {
417 if ((ratio = avg_stats(&walltime_nsecs_stats)) != 0) 450 if ((ratio = avg_stats(&walltime_nsecs_stats)) != 0)
418 fprintf(out, " # %8.3f CPUs utilized ", avg / ratio); 451 print_metric(ctxp, NULL, "%8.3f", "CPUs utilized",
452 avg / ratio);
419 else 453 else
420 fprintf(out, " "); 454 print_metric(ctxp, NULL, NULL, "CPUs utilized", 0);
421 } else if (runtime_nsecs_stats[cpu].n != 0) { 455 } else if (runtime_nsecs_stats[cpu].n != 0) {
422 char unit = 'M'; 456 char unit = 'M';
457 char unit_buf[10];
423 458
424 total = avg_stats(&runtime_nsecs_stats[cpu]); 459 total = avg_stats(&runtime_nsecs_stats[cpu]);
425 460
@@ -429,9 +464,9 @@ void perf_stat__print_shadow_stats(FILE *out, struct perf_evsel *evsel,
429 ratio *= 1000; 464 ratio *= 1000;
430 unit = 'K'; 465 unit = 'K';
431 } 466 }
432 467 snprintf(unit_buf, sizeof(unit_buf), "%c/sec", unit);
433 fprintf(out, " # %8.3f %c/sec ", ratio, unit); 468 print_metric(ctxp, NULL, "%8.3f", unit_buf, ratio);
434 } else { 469 } else {
435 fprintf(out, " "); 470 print_metric(ctxp, NULL, NULL, NULL, 0);
436 } 471 }
437} 472}