@@ -2946,7 +2946,7 @@ hwc_memop_string (ABST_type memop)
break;
case ABST_EXACT_PEBS_PLUS1:
case ABST_EXACT:
- s = GTXT ("memoryspace ");
+ s = GTXT ("memoryspace (precise) ");
break;
case ABST_COUNT:
s = GTXT ("count ");
@@ -3656,31 +3656,83 @@ hwc_usage_internal (int forKernel, FILE *f_usage, const char *cmd, const char *d
/* long listings */
char tmp[1024];
+ /* Counters whose memop is ABST_EXACT or ABST_EXACT_PEBS_PLUS1 deliver
+ precise PC attribution (IBS on AMD, PEBS on Intel). All others can
+ skid forward by several instructions, which is the single most common
+ source of user confusion when reading source-view reports. Group the
+ listing so the precise events are visible and labeled. */
+#define HWC_IS_PRECISE(ctr) \
+ (HWCENTRY_USES_SAMPLING (ctr) || (ctr)->memop == ABST_EXACT)
+
if (has_std_ctrs)
{
- fprintf (f_usage, GTXT ("\nAliases for most useful HW counters:\n\n"));
- format_columns (tmp, 1024, "alias", "raw name", "type ", "units", "description");
- fprintf (f_usage, NTXT (" %s\n\n"), tmp);
+ int n_precise = 0;
for (Hwcentry **pctr = std_ctrs; *pctr; pctr++)
+ if (HWC_IS_PRECISE (*pctr))
+ n_precise++;
+
+ fprintf (f_usage, GTXT ("\nAliases for most useful HW counters:\n"));
+ if (n_precise)
{
- Hwcentry *ctr = *pctr;
- hwc_hwcentry_string_internal (tmp, sizeof (tmp), ctr, 0);
- fprintf (f_usage, NTXT (" %s\n"), tmp);
+ fprintf (f_usage, GTXT ("\n Precise events (recommended for accurate"
+ " instruction/line attribution):\n\n"));
+ format_columns (tmp, 1024, "alias", "raw name", "type ", "units", "description");
+ fprintf (f_usage, NTXT (" %s\n\n"), tmp);
+ for (Hwcentry **pctr = std_ctrs; *pctr; pctr++)
+ if (HWC_IS_PRECISE (*pctr))
+ {
+ hwc_hwcentry_string_internal (tmp, sizeof (tmp), *pctr, 0);
+ fprintf (f_usage, NTXT (" %s\n"), tmp);
+ }
}
+
+ fprintf (f_usage, GTXT ("\n Standard events (sample location may"
+ " skid forward several instructions):\n\n"));
+ format_columns (tmp, 1024, "alias", "raw name", "type ", "units", "description");
+ fprintf (f_usage, NTXT (" %s\n\n"), tmp);
+ for (Hwcentry **pctr = std_ctrs; *pctr; pctr++)
+ if (!HWC_IS_PRECISE (*pctr))
+ {
+ hwc_hwcentry_string_internal (tmp, sizeof (tmp), *pctr, 0);
+ fprintf (f_usage, NTXT (" %s\n"), tmp);
+ }
}
if (has_raw_ctrs)
{
- fprintf (f_usage, GTXT ("\nRaw HW counters:\n\n"));
+ int n_precise = 0;
+ for (Hwcentry **pctr = raw_ctrs; *pctr; pctr++)
+ if (HWC_IS_PRECISE (*pctr))
+ n_precise++;
+
+ fprintf (f_usage, GTXT ("\nRaw HW counters:\n"));
hwc_usage_raw_overview_sparc (f_usage, cpuver);
+
+ if (n_precise)
+ {
+ fprintf (f_usage, GTXT ("\n Precise events (recommended for accurate"
+ " instruction/line attribution):\n\n"));
+ format_columns (tmp, 1024, "name", NULL, "type ", "units", "description");
+ fprintf (f_usage, NTXT (" %s\n\n"), tmp);
+ for (Hwcentry **pctr = raw_ctrs; *pctr; pctr++)
+ if (HWC_IS_PRECISE (*pctr))
+ {
+ hwc_hwcentry_string_internal (tmp, sizeof (tmp), *pctr, show_short_desc);
+ fprintf (f_usage, NTXT (" %s\n"), tmp);
+ }
+ }
+
+ fprintf (f_usage, GTXT ("\n Standard events (sample location may"
+ " skid forward several instructions):\n\n"));
format_columns (tmp, 1024, "name", NULL, "type ", "units", "description");
fprintf (f_usage, NTXT (" %s\n\n"), tmp);
for (Hwcentry **pctr = raw_ctrs; *pctr; pctr++)
- {
- Hwcentry *ctr = *pctr;
- hwc_hwcentry_string_internal (tmp, sizeof (tmp), ctr, show_short_desc);
- fprintf (f_usage, NTXT (" %s\n"), tmp);
- }
+ if (!HWC_IS_PRECISE (*pctr))
+ {
+ hwc_hwcentry_string_internal (tmp, sizeof (tmp), *pctr, show_short_desc);
+ fprintf (f_usage, NTXT (" %s\n"), tmp);
+ }
}
+#undef HWC_IS_PRECISE
/* documentation notice */
hwc_get_docref (tmp, 1024);