This patch adds the basic capability to scale the perf counters for
perf derived events. Many of the hardware counters don't make sense if
the raw value is directly used. If a scale is known for a counter, it
should be given with the counter name in perfevent.conf. The scale is
a simple floating point value.
[read_bandwidth:derived]
snbep_unc_imc0::UNC_M_CAS_COUNT:RD node 0.000061
snbep_unc_imc1::UNC_M_CAS_COUNT:RD node 0.000061
snbep_unc_imc2::UNC_M_CAS_COUNT:RD node 0.000061
snbep_unc_imc3::UNC_M_CAS_COUNT:RD node 0.000061
# pmval perfevent.derived.read_bandwidth.value
metric: perfevent.derived.read_bandwidth.value
host: <host>
semantics: cumulative counter (converting to rate)
units: count (converting to count / sec)
samples: all
cpu0 cpu8
37.46 18.30
37.67 20.08
37.53 19.72
The above shows the memory read bandwidth per node on a x86
machine scaled to MiB/s.
Signed-off-by: Hemant Kumar <hemant@xxxxxxxxxxxxxxxxxx>
---
src/pmdas/perfevent/configparser.h | 1 +
src/pmdas/perfevent/configparser.l | 28 ++++++++++++++++++++++++++++
src/pmdas/perfevent/perfevent.conf | 13 +++++++------
src/pmdas/perfevent/perfinterface.c | 8 ++++++--
src/pmdas/perfevent/perfinterface.h | 3 ++-
5 files changed, 44 insertions(+), 9 deletions(-)
diff --git a/src/pmdas/perfevent/configparser.h
b/src/pmdas/perfevent/configparser.h
index a614ffc..f7ed02f 100644
--- a/src/pmdas/perfevent/configparser.h
+++ b/src/pmdas/perfevent/configparser.h
@@ -34,6 +34,7 @@ typedef struct pmctype {
typedef struct pmcsetting {
char *name;
int cpuConfig;
+ double scale; /* Currently, only used by derived events */
struct pmcsetting *next;
} pmcsetting_t;
diff --git a/src/pmdas/perfevent/configparser.l
b/src/pmdas/perfevent/configparser.l
index 13a4bc2..f22c816 100644
--- a/src/pmdas/perfevent/configparser.l
+++ b/src/pmdas/perfevent/configparser.l
@@ -107,6 +107,7 @@ static void add_pmc_setting_name_derived(configuration_t
*config, char *name)
newpmcderivedsetting = calloc(1, sizeof *newpmcderivedsetting);
newpmcderivedsetting->name = strdup(name);
newpmcderivedsetting->cpuConfig = CPUCONFIG_EACH_CPU;
+ newpmcderivedsetting->scale = 1.0;
newpmcderivedsetting->next = NULL;
setting_lists = entry->setting_lists;
@@ -206,6 +207,32 @@ static void add_pmcsetting_name(configuration_t *config,
char *name)
entry->pmcSettingList = newpmcsetting;
}
+static void set_pmcsetting_derived_scale(configuration_t *config, double
scale)
+{
+ pmcsetting_t *pmcsetting;
+ pmcSettingLists_t *setting_lists;
+
+ if ((NULL == config) || (0 == config->nConfigEntries))
+ {
+ return;
+ }
+
+ if (context_derived)
+ {
+ setting_lists =
config->derivedArr[config->nDerivedEntries-1].setting_lists;
+ while (setting_lists->next)
+ {
+ setting_lists = setting_lists->next;
+ }
+ pmcsetting = setting_lists->derivedSettingList;
+ while(pmcsetting->next)
+ {
+ pmcsetting = pmcsetting->next;
+ }
+ pmcsetting->scale = scale;
+ }
+}
+
static void set_pmcsetting_cpuconfig(configuration_t *config, int cpuconfig)
{
pmcsetting_t *pmcsetting;
@@ -374,6 +401,7 @@ cpu_rr set_pmcsetting_cpuconfig(yyextra,
CPUCONFIG_ROUNDROBIN_CPU);
node set_pmcsetting_cpuconfig(yyextra, CPUCONFIG_EACH_NUMANODE);
node_rr set_pmcsetting_cpuconfig(yyextra, CPUCONFIG_ROUNDROBIN_NUMANODE);
[0-9]* set_pmcsetting_cpuconfig(yyextra, atoi(yytext) );
+([0-9]*\.[0-9]+([eE][-+]?[0-9]+)?) set_pmcsetting_derived_scale(yyextra,
strtod(yytext, NULL));
}
<*>.|\n { fprintf(stderr, "Syntax error on line: %d \n", yylineno); return -1;
}
diff --git a/src/pmdas/perfevent/perfevent.conf
b/src/pmdas/perfevent/perfevent.conf
index 9826bef..20bf43c 100644
--- a/src/pmdas/perfevent/perfevent.conf
+++ b/src/pmdas/perfevent/perfevent.conf
@@ -13,16 +13,17 @@
#
# For derived events :
# [event:derived]
-# EVENT_NAME [CPU OPTION]
-# where the CPU OPTION must match for all the events in a derived event.
+# EVENT_NAME [CPU OPTION] [scale]
+# where the CPU OPTION must match for all the events in a derived event,
+# scale is a floating value and can be used to scale the event values.
#
# Derived events also have the capability of alternate event groups.
# [event:derived]
-# EVENT_NAME1 [CPU OPTION]
-# EVENT_NAME2 [CPU OPTION]
+# EVENT_NAME1 [CPU OPTION] [scale]
+# EVENT_NAME2 [CPU OPTION] [scale]
# ||
-# EVENT_NAME3 [CPU OPTION]
-# EVENT_NAME4 [CPU OPTION]
+# EVENT_NAME3 [CPU OPTION] [scale]
+# EVENT_NAME4 [CPU OPTION] [scale]
# ||
# ...
# If specified like above, depending on the availability of the events,
diff --git a/src/pmdas/perfevent/perfinterface.c
b/src/pmdas/perfevent/perfinterface.c
index bf4b0d9..500fa2c 100644
--- a/src/pmdas/perfevent/perfinterface.c
+++ b/src/pmdas/perfevent/perfinterface.c
@@ -55,6 +55,7 @@ typedef struct event_t_ {
typedef struct event_list_t_ {
event_t *event;
+ double scale;
struct event_list_t_ *next;
} event_list_t;
@@ -232,7 +233,6 @@ static int perf_setup_derived_event(perfdata_t *inst,
pmcderived_t *derived_pmc)
free_event_list(event_list);
return -E_PERFEVENT_LOGIC;
}
- derived_setting = derived_setting->next;
tmp = calloc(1, sizeof(*tmp));
if (NULL == tmp) {
@@ -240,7 +240,9 @@ static int perf_setup_derived_event(perfdata_t *inst,
pmcderived_t *derived_pmc)
return -E_PERFEVENT_REALLOC;
}
tmp->event = event;
+ tmp->scale = derived_setting->scale;
tmp->next = NULL;
+ derived_setting = derived_setting->next;
if (NULL == event_list) {
event_list = tmp;
@@ -674,6 +676,7 @@ static int perf_derived_get(perf_derived_counter
**derived_counters,
if (!ptr)
return -E_PERFEVENT_REALLOC;
ptr->counter = counter;
+ ptr->scale = event_list->scale;
ptr->next = NULL;
if (counter_list == NULL) {
counter_list = ptr;
@@ -710,7 +713,8 @@ static int perf_derived_get(perf_derived_counter
**derived_counters,
clist = pdcounter[idx].counter_list;
while(clist) {
ctr = clist->counter;
- pdcounter[idx].data[cpuidx].value +=
ctr->data[cpuidx].value;
+ pdcounter[idx].data[cpuidx].value +=
(ctr->data[cpuidx].value *
+ clist->scale);
clist = clist->next;
}
}
diff --git a/src/pmdas/perfevent/perfinterface.h
b/src/pmdas/perfevent/perfinterface.h
index 1fc6223..e471382 100644
--- a/src/pmdas/perfevent/perfinterface.h
+++ b/src/pmdas/perfevent/perfinterface.h
@@ -35,12 +35,13 @@ typedef struct perf_counter_t_
typedef struct perf_derived_data_t_
{
- uint64_t value;
+ double value;
} perf_derived_data;
typedef struct perf_counter_list_t_
{
perf_counter *counter;
+ double scale;
struct perf_counter_list_t_ *next;
} perf_counter_list;
--
1.9.3
|