61 if ((
char *)a->
stat < (
char *)b->
stat)
91 v = container_of(rb_node,
struct saved_value, rb_node);
151 if (evsel->
attr.exclude_kernel)
153 if (evsel->
attr.exclude_user)
155 if (evsel->
attr.exclude_hv)
157 if (evsel->
attr.exclude_host)
159 if (evsel->
attr.exclude_idle)
171 next = rb_first(&rblist->
entries);
177 sizeof(
struct stats));
194 int ctx,
int cpu, u64 count)
213 count *= counter->
scale;
283 static const double grc_table[
GRC_MAX_NR][3] = {
290 if (ratio > grc_table[type][0])
292 else if (ratio > grc_table[type][1])
294 else if (ratio > grc_table[type][2])
306 if (!strcasecmp(c2->
name, name))
317 const char **metric_names;
319 int num_metric_names;
322 bool invalid =
false;
328 if (!metric_events) {
330 &metric_names, &num_metric_names) < 0)
333 metric_events = calloc(
sizeof(
struct perf_evsel *),
334 num_metric_names + 1);
340 for (i = 0; i < num_metric_names; i++) {
345 if (!strcasecmp(oc->
name, metric_names[i])) {
357 static char *printed;
366 if (!printed || strcasecmp(printed, metric_names[i])) {
368 "Add %s event to groups to get metric expression for %s\n",
371 printed = strdup(metric_names[i]);
376 metric_events[i] = oc;
379 metric_events[i] = NULL;
418 double total, ratio = 0.0;
425 ratio = avg / total * 100.0;
441 double total, ratio = 0.0;
448 ratio = avg / total * 100.0;
452 out->
print_metric(out->
ctx, color,
"%7.2f%%",
"backend cycles idle", ratio);
461 double total, ratio = 0.0;
468 ratio = avg / total * 100.0;
472 out->
print_metric(out->
ctx, color,
"%7.2f%%",
"of all branches", ratio);
482 double total, ratio = 0.0;
489 ratio = avg / total * 100.0;
493 out->
print_metric(out->
ctx, color,
"%7.2f%%",
"of all L1-dcache hits", ratio);
503 double total, ratio = 0.0;
510 ratio = avg / total * 100.0;
513 out->
print_metric(out->
ctx, color,
"%7.2f%%",
"of all L1-icache hits", ratio);
522 double total, ratio = 0.0;
529 ratio = avg / total * 100.0;
532 out->
print_metric(out->
ctx, color,
"%7.2f%%",
"of all dTLB cache hits", ratio);
541 double total, ratio = 0.0;
548 ratio = avg / total * 100.0;
551 out->
print_metric(out->
ctx, color,
"%7.2f%%",
"of all iTLB cache hits", ratio);
560 double total, ratio = 0.0;
567 ratio = avg / total * 100.0;
570 out->
print_metric(out->
ctx, color,
"%7.2f%%",
"of all LL-cache hits", ratio);
617 if (x < 0 && x >= -0.02)
639 bad_spec = total / total_slots;
651 retiring = ret_slots / total_slots;
663 fe_bound = fetch_bub / total_slots;
681 double smi_num, aperf, cycles, cost = 0.0;
683 const char *color = NULL;
689 if ((cycles == 0) || (aperf == 0))
693 cost = (aperf - cycles) / aperf * 100.00;
704 const char *metric_name,
714 void *ctxp = out->
ctx;
718 for (i = 0; metric_events[i]; i++) {
723 if (!strcmp(metric_events[i]->name,
"duration_time")) {
736 if (!metric_events[i]) {
737 const char *p = metric_expr;
740 print_metric(ctxp, NULL,
"%8.1f",
746 print_metric(ctxp, NULL, NULL,
748 (metric_name ? metric_name : name) :
"", 0);
750 print_metric(ctxp, NULL, NULL,
"", 0);
759 void *ctxp = out->
ctx;
761 double total, ratio = 0.0, total2;
762 const char *color = NULL;
772 print_metric(ctxp, NULL,
"%7.2f ",
773 "insn per cycle", ratio);
775 print_metric(ctxp, NULL, NULL,
"insn per cycle", 0);
788 print_metric(ctxp, NULL,
"%7.2f ",
789 "stalled cycles per insn",
792 print_metric(ctxp, NULL, NULL,
793 "stalled cycles per insn", 0);
799 print_metric(ctxp, NULL, NULL,
"of all branches", 0);
801 evsel->
attr.type == PERF_TYPE_HW_CACHE &&
802 evsel->
attr.config == ( PERF_COUNT_HW_CACHE_L1D |
803 ((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
804 ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16))) {
809 print_metric(ctxp, NULL, NULL,
"of all L1-dcache hits", 0);
811 evsel->
attr.type == PERF_TYPE_HW_CACHE &&
812 evsel->
attr.config == ( PERF_COUNT_HW_CACHE_L1I |
813 ((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
814 ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16))) {
819 print_metric(ctxp, NULL, NULL,
"of all L1-icache hits", 0);
821 evsel->
attr.type == PERF_TYPE_HW_CACHE &&
822 evsel->
attr.config == ( PERF_COUNT_HW_CACHE_DTLB |
823 ((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
824 ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16))) {
829 print_metric(ctxp, NULL, NULL,
"of all dTLB cache hits", 0);
831 evsel->
attr.type == PERF_TYPE_HW_CACHE &&
832 evsel->
attr.config == ( PERF_COUNT_HW_CACHE_ITLB |
833 ((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
834 ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16))) {
839 print_metric(ctxp, NULL, NULL,
"of all iTLB cache hits", 0);
841 evsel->
attr.type == PERF_TYPE_HW_CACHE &&
842 evsel->
attr.config == ( PERF_COUNT_HW_CACHE_LL |
843 ((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
844 ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16))) {
849 print_metric(ctxp, NULL, NULL,
"of all LL-cache hits", 0);
854 ratio = avg * 100 / total;
857 print_metric(ctxp, NULL,
"%8.3f %%",
858 "of all cache refs", ratio);
860 print_metric(ctxp, NULL, NULL,
"of all cache refs", 0);
870 print_metric(ctxp, NULL,
"%8.3f",
"GHz", ratio);
872 print_metric(ctxp, NULL, NULL,
"Ghz", 0);
878 print_metric(ctxp, NULL,
879 "%7.2f%%",
"transactional cycles",
880 100.0 * (avg / total));
882 print_metric(ctxp, NULL, NULL,
"transactional cycles",
891 print_metric(ctxp, NULL,
"%7.2f%%",
"aborted cycles",
892 100.0 * ((total2-avg) / total));
894 print_metric(ctxp, NULL, NULL,
"aborted cycles", 0);
903 print_metric(ctxp, NULL,
"%8.0f",
904 "cycles / transaction", ratio);
906 print_metric(ctxp, NULL, NULL,
"cycles / transaction",
915 print_metric(ctxp, NULL,
"%8.0f",
"cycles / elision", ratio);
919 print_metric(ctxp, NULL,
"%8.3f",
"CPUs utilized",
922 print_metric(ctxp, NULL, NULL,
"CPUs utilized", 0);
928 print_metric(ctxp, color,
"%8.1f%%",
"frontend bound",
935 print_metric(ctxp, color,
"%8.1f%%",
"retiring",
942 print_metric(ctxp, color,
"%8.1f%%",
"bad speculation",
946 const char *
name =
"backend bound";
947 static int have_recovery_bubbles = -1;
950 if (have_recovery_bubbles < 0)
952 "topdown-recovery-bubbles");
953 if (!have_recovery_bubbles)
954 name =
"backend bound/bad spec";
959 print_metric(ctxp, color,
"%8.1f%%", name,
962 print_metric(ctxp, NULL, NULL, name, 0);
973 ratio = 1000.0 * avg / total;
978 snprintf(unit_buf,
sizeof(unit_buf),
"%c/sec", unit);
979 print_metric(ctxp, NULL,
"%8.3f", unit_buf, ratio);
989 list_for_each_entry (mexp, &me->
head,
nd) {
998 print_metric(ctxp, NULL, NULL, NULL, 0);
static void print_l1_icache_misses(int cpu, struct perf_evsel *evsel, double avg, struct perf_stat_output_ctx *out, struct runtime_stat *st)
void perf_stat__print_shadow_stats(struct perf_evsel *evsel, double avg, int cpu, struct perf_stat_output_ctx *out, struct rblist *metric_events, struct runtime_stat *st)
static int saved_value_cmp(struct rb_node *rb_node, const void *entry)
static double sanitize_val(double x)
static void print_branch_misses(int cpu, struct perf_evsel *evsel, double avg, struct perf_stat_output_ctx *out, struct runtime_stat *st)
double avg_stats(struct stats *stats)
struct perf_evsel * evsel
static const char * get_ratio_color(enum grc_type type, double ratio)
#define perf_stat_evsel__is(evsel, id)
static void print_l1_dcache_misses(int cpu, struct perf_evsel *evsel, double avg, struct perf_stat_output_ctx *out, struct runtime_stat *st)
#define PERF_COLOR_MAGENTA
void runtime_stat__exit(struct runtime_stat *st)
static struct perf_evsel * perf_stat__find_event(struct perf_evlist *evsel_list, const char *name)
static void print_itlb_cache_misses(int cpu, struct perf_evsel *evsel, double avg, struct perf_stat_output_ctx *out, struct runtime_stat *st)
static void print_stalled_cycles_frontend(int cpu, struct perf_evsel *evsel, double avg, struct perf_stat_output_ctx *out, struct runtime_stat *st)
print_metric_t print_metric
static void generic_metric(const char *metric_expr, struct perf_evsel **metric_events, char *name, const char *metric_name, double avg, int cpu, struct perf_stat_output_ctx *out, struct runtime_stat *st)
static struct rblist metric_events
int(* node_cmp)(struct rb_node *rbn, const void *entry)
struct runtime_stat rt_stat
x86 movsq based memset() in arch/x86/lib/memset_64.S") MEMSET_FN(memset_erms
static double td_be_bound(int ctx, int cpu, struct runtime_stat *st)
struct stats walltime_nsecs_stats
#define PERF_COLOR_NORMAL
void(* node_delete)(struct rblist *rblist, struct rb_node *rb_node)
void expr__ctx_init(struct parse_ctx *ctx)
static void print_ll_cache_misses(int cpu, struct perf_evsel *evsel, double avg, struct perf_stat_output_ctx *out, struct runtime_stat *st)
static void reset_stat(struct runtime_stat *st)
struct rb_node * rblist__find(struct rblist *rblist, const void *entry)
void update_stats(struct stats *stats, u64 val)
#define evlist__for_each_entry(evlist, evsel)
static struct perf_evlist * evsel_list
struct perf_evsel ** metric_events
void perf_stat__collect_metric_expr(struct perf_evlist *evsel_list)
static double td_bad_spec(int ctx, int cpu, struct runtime_stat *st)
static int entry(u64 ip, struct unwind_info *ui)
bool pmu_have_event(const char *pname, const char *name)
static bool have_frontend_stalled
void perf_stat__reset_shadow_per_stat(struct runtime_stat *st)
void rblist__exit(struct rblist *rblist)
struct metric_event * metricgroup__lookup(struct rblist *metric_events, struct perf_evsel *evsel, bool create)
x86 movsq based memcpy() in arch/x86/lib/memcpy_64.S") MEMCPY_FN(memcpy_erms
static struct rb_node * saved_value_new(struct rblist *rblist __maybe_unused, const void *entry)
static void update_runtime_stat(struct runtime_stat *st, enum stat_type type, int ctx, int cpu, u64 count)
struct rb_node *(* node_new)(struct rblist *rlist, const void *new_entry)
void perf_stat__init_shadow_stats(void)
void perf_stat__update_shadow_stats(struct perf_evsel *counter, u64 count, int cpu, struct runtime_stat *st)
void rblist__init(struct rblist *rblist)
static struct saved_value * saved_value_lookup(struct perf_evsel *evsel, int cpu, bool create, enum stat_type type, int ctx, struct runtime_stat *st)
#define for_each_group_member(_evsel, _leader)
void runtime_stat__init(struct runtime_stat *st)
#define perf_evsel__match(evsel, t, c)
int rblist__add_node(struct rblist *rblist, const void *new_entry)
struct perf_evsel * leader
void(* print_metric_t)(void *ctx, const char *color, const char *unit, const char *fmt, double val)
static double td_total_slots(int ctx, int cpu, struct runtime_stat *st)
void perf_stat__reset_shadow_stats(void)
static void print_stalled_cycles_backend(int cpu, struct perf_evsel *evsel, double avg, struct perf_stat_output_ctx *out, struct runtime_stat *st)
static double runtime_stat_n(struct runtime_stat *st, enum stat_type type, int ctx, int cpu)
struct perf_evsel ** metric_events
static double td_fe_bound(int ctx, int cpu, struct runtime_stat *st)
static void saved_value_delete(struct rblist *rblist __maybe_unused, struct rb_node *rb_node)
#define PERF_COLOR_YELLOW
static void print_dtlb_cache_misses(int cpu, struct perf_evsel *evsel, double avg, struct perf_stat_output_ctx *out, struct runtime_stat *st)
int expr__parse(double *final_val, struct parse_ctx *ctx, const char **pp)
void expr__add_id(struct parse_ctx *ctx, const char *name, double val)
static void print_smi_cost(int cpu, struct perf_evsel *evsel, struct perf_stat_output_ctx *out, struct runtime_stat *st)
static double runtime_stat_avg(struct runtime_stat *st, enum stat_type type, int ctx, int cpu)
struct perf_event_attr attr
static double td_retiring(int ctx, int cpu, struct runtime_stat *st)
int expr__find_other(const char *p, const char *one, const char ***other, int *num_otherp)
struct runtime_stat * stat
static int evsel_context(struct perf_evsel *evsel)