modified programmable perf. ctr. configuration

This commit is contained in:
Andreas Abel
2021-10-28 20:29:26 +02:00
parent 44bcccfa07
commit 645d7c7b92
4 changed files with 34 additions and 42 deletions

View File

@@ -148,6 +148,7 @@ void parse_counter_configs() {
} }
pfc_configs[n_pfc_configs] = (struct pfc_config){0}; pfc_configs[n_pfc_configs] = (struct pfc_config){0};
pfc_configs[n_pfc_configs].ctr = -1;
char* config_str = strsep(&line, " \t"); char* config_str = strsep(&line, " \t");
@@ -192,15 +193,7 @@ void parse_counter_configs() {
print_error("invalid counter: %s\n", ce); print_error("invalid counter: %s\n", ce);
continue; continue;
} }
size_t prev_n_pfc_configs = n_pfc_configs; pfc_configs[n_pfc_configs].ctr = counter;
while (n_pfc_configs % n_programmable_counters != counter) {
pfc_configs[n_pfc_configs].invalid = 1;
n_pfc_configs++;
}
if (prev_n_pfc_configs != n_pfc_configs) {
pfc_configs[n_pfc_configs] = pfc_configs[prev_n_pfc_configs];
pfc_configs[n_pfc_configs].invalid = 0;
}
} else if (!strncmp(ce, "CMSK=", 5)) { } else if (!strncmp(ce, "CMSK=", 5)) {
nb_strtoul(ce+5, 0, &(pfc_configs[n_pfc_configs].cmask)); nb_strtoul(ce+5, 0, &(pfc_configs[n_pfc_configs].cmask));
} else if (!strncmp(ce, "MSR_3F6H=", 9)) { } else if (!strncmp(ce, "MSR_3F6H=", 9)) {
@@ -327,32 +320,29 @@ void configure_perf_ctrs_FF(unsigned int usr, unsigned int os) {
} }
} }
void configure_perf_ctrs_programmable(int start, int end, unsigned int usr, unsigned int os) { size_t configure_perf_ctrs_programmable(size_t next_pfc_config, unsigned int usr, unsigned int os, char* descriptions[]) {
if (is_Intel_CPU) { if (is_Intel_CPU) {
uint64_t global_ctrl = read_msr(MSR_IA32_PERF_GLOBAL_CTRL); uint64_t global_ctrl = read_msr(MSR_IA32_PERF_GLOBAL_CTRL);
global_ctrl |= ((uint64_t)7 << 32) | 15; global_ctrl |= ((uint64_t)7 << 32) | 15;
write_msr(MSR_IA32_PERF_GLOBAL_CTRL, global_ctrl); write_msr(MSR_IA32_PERF_GLOBAL_CTRL, global_ctrl);
for (int i=0; i<n_programmable_counters; i++) { for (int i=0; i<n_programmable_counters; i++) {
uint64_t perfevtselx = read_msr(MSR_IA32_PERFEVTSEL0+i);
// disable counter i
perfevtselx &= ~(((uint64_t)1 << 32) - 1);
write_msr(MSR_IA32_PERFEVTSEL0+i, perfevtselx);
// clear // clear
write_msr(MSR_IA32_PMC0+i, 0); write_msr(MSR_IA32_PMC0+i, 0);
if (start+i >= end) { if (next_pfc_config >= n_pfc_configs) {
continue; return next_pfc_config;
} }
// configure counter i struct pfc_config config = pfc_configs[next_pfc_config];
struct pfc_config config = pfc_configs[start+i]; if ((config.ctr != -1) && (config.ctr != i)) {
if (config.invalid) {
continue; continue;
} }
perfevtselx |= ((config.cmask & 0xFF) << 24); next_pfc_config++;
descriptions[i] = config.description;
uint64_t perfevtselx = ((config.cmask & 0xFF) << 24);
perfevtselx |= (config.inv << 23); perfevtselx |= (config.inv << 23);
perfevtselx |= (1ULL << 22); perfevtselx |= (1ULL << 22);
perfevtselx |= (config.any << 21); perfevtselx |= (config.any << 21);
@@ -366,11 +356,9 @@ void configure_perf_ctrs_programmable(int start, int end, unsigned int usr, unsi
if (config.msr_3f6h) { if (config.msr_3f6h) {
write_msr(0x3f6, config.msr_3f6h); write_msr(0x3f6, config.msr_3f6h);
} }
if (config.msr_pf) { if (config.msr_pf) {
write_msr(MSR_PEBS_FRONTEND, config.msr_pf); write_msr(MSR_PEBS_FRONTEND, config.msr_pf);
} }
if (config.msr_rsp0) { if (config.msr_rsp0) {
write_msr(MSR_OFFCORE_RSP0, config.msr_rsp0); write_msr(MSR_OFFCORE_RSP0, config.msr_rsp0);
} }
@@ -383,12 +371,15 @@ void configure_perf_ctrs_programmable(int start, int end, unsigned int usr, unsi
// clear // clear
write_msr(CORE_X86_MSR_PERF_CTR+(2*i), 0); write_msr(CORE_X86_MSR_PERF_CTR+(2*i), 0);
if (start+i >= end) { if (next_pfc_config >= n_pfc_configs) {
write_msr(CORE_X86_MSR_PERF_CTL + (2*i), 0); write_msr(CORE_X86_MSR_PERF_CTL + (2*i), 0);
continue; continue;
} }
struct pfc_config config = pfc_configs[start+i]; struct pfc_config config = pfc_configs[next_pfc_config];
next_pfc_config++;
descriptions[i] = config.description;
uint64_t perf_ctl = 0; uint64_t perf_ctl = 0;
perf_ctl |= ((config.evt_num) & 0xF00) << 24; perf_ctl |= ((config.evt_num) & 0xF00) << 24;
@@ -404,6 +395,7 @@ void configure_perf_ctrs_programmable(int start, int end, unsigned int usr, unsi
write_msr(CORE_X86_MSR_PERF_CTL + (2*i), perf_ctl); write_msr(CORE_X86_MSR_PERF_CTL + (2*i), perf_ctl);
} }
} }
return next_pfc_config;
} }
void configure_MSRs(struct msr_config config) { void configure_MSRs(struct msr_config config) {

View File

@@ -149,7 +149,7 @@ struct pfc_config {
unsigned long msr_pf; unsigned long msr_pf;
unsigned long msr_rsp0; unsigned long msr_rsp0;
unsigned long msr_rsp1; unsigned long msr_rsp1;
unsigned int invalid; unsigned int ctr;
char* description; char* description;
}; };
extern struct pfc_config pfc_configs[]; extern struct pfc_config pfc_configs[];
@@ -215,8 +215,9 @@ void write_msr(unsigned int msr, uint64_t value);
void configure_perf_ctrs_FF(unsigned int usr, unsigned int os); void configure_perf_ctrs_FF(unsigned int usr, unsigned int os);
// Clears the programmable performance counters and writes the configurations to the corresponding MSRs. // Clears the programmable performance counters and writes the configurations to the corresponding MSRs.
// start and end are indices into the pfc_configs array. // next_pfc_config is an index into the pfc_configs array; the function takes up to n_programmable_counters many configurations from this array;
void configure_perf_ctrs_programmable(int start, int end, unsigned int usr, unsigned int os); // it returns the index of the next configuration, and writes the descriptions of the applicable configurations to the corresponding array.
size_t configure_perf_ctrs_programmable(size_t next_pfc_config, unsigned int usr, unsigned int os, char* descriptions[]);
void configure_MSRs(struct msr_config config); void configure_MSRs(struct msr_config config);

View File

@@ -577,8 +577,10 @@ static int show(struct seq_file *m, void *v) {
} }
} }
for (size_t i=0; i<n_pfc_configs; i+=n_programmable_counters) { size_t next_pfc_config = 0;
configure_perf_ctrs_programmable(i, min(i+n_programmable_counters, n_pfc_configs), 1, 1); while (next_pfc_config < n_pfc_configs) {
char* pfc_descriptions[MAX_PROGRAMMABLE_COUNTERS] = {0};
next_pfc_config = configure_perf_ctrs_programmable(next_pfc_config, 1, 1, pfc_descriptions);
// on some microarchitectures (e.g., Broadwell), some events (e.g., L1 misses) are not counted properly if only the OS field is set // on some microarchitectures (e.g., Broadwell), some events (e.g., L1 misses) are not counted properly if only the OS field is set
run_experiment(measurement_template, measurement_results_base, n_programmable_counters, base_unroll_count, base_loop_count); run_experiment(measurement_template, measurement_results_base, n_programmable_counters, base_unroll_count, base_loop_count);
@@ -591,8 +593,8 @@ static int show(struct seq_file *m, void *v) {
print_all_measurement_results(measurement_results, n_programmable_counters); print_all_measurement_results(measurement_results, n_programmable_counters);
} }
for (int c=0; c < n_programmable_counters && i + c < n_pfc_configs; c++) { for (size_t c=0; c < n_programmable_counters; c++) {
if (!pfc_configs[i+c].invalid) seq_printf(m, "%s", compute_result_str(buf, sizeof(buf), pfc_configs[i+c].description, c)); if (pfc_descriptions[c]) seq_printf(m, "%s", compute_result_str(buf, sizeof(buf), pfc_descriptions[c], c));
} }
} }

View File

@@ -319,13 +319,10 @@ int main(int argc, char **argv) {
} }
} }
for (size_t i=0; i<n_pfc_configs; i+=n_programmable_counters) { size_t next_pfc_config = 0;
size_t end = i + n_programmable_counters; while (next_pfc_config < n_pfc_configs) {
if (end > n_pfc_configs) { char* pfc_descriptions[MAX_PROGRAMMABLE_COUNTERS] = {0};
end = n_pfc_configs; next_pfc_config = configure_perf_ctrs_programmable(next_pfc_config, usr, os, pfc_descriptions);
}
configure_perf_ctrs_programmable(i, end, usr, os);
run_experiment(measurement_template, measurement_results_base, n_programmable_counters, base_unroll_count, base_loop_count); run_experiment(measurement_template, measurement_results_base, n_programmable_counters, base_unroll_count, base_loop_count);
run_experiment(measurement_template, measurement_results, n_programmable_counters, main_unroll_count, main_loop_count); run_experiment(measurement_template, measurement_results, n_programmable_counters, main_unroll_count, main_loop_count);
@@ -337,8 +334,8 @@ int main(int argc, char **argv) {
print_all_measurement_results(measurement_results, n_programmable_counters); print_all_measurement_results(measurement_results, n_programmable_counters);
} }
for (int c=0; c < n_programmable_counters && i + c < n_pfc_configs; c++) { for (size_t c=0; c < n_programmable_counters; c++) {
if (!pfc_configs[i+c].invalid) printf("%s", compute_result_str(buf, sizeof(buf), pfc_configs[i+c].description, c)); if (pfc_descriptions[c]) printf("%s", compute_result_str(buf, sizeof(buf), pfc_descriptions[c], c));
} }
} }