diff --git a/counters.h b/counters.h index 15926127826cb8745e740cd315eef88617112835..751557ab5b308c0eda13c61f077d5bdff6519cd1 100644 --- a/counters.h +++ b/counters.h @@ -18,12 +18,9 @@ *******************************************************/ -#include <linux/perf_event.h> +unsigned int init_counters(char*, void **); +unsigned int get_counters(uint64_t* results, void*); +void clean_counters(void *); +void label_counters(char **labels, void*); -typedef struct _counter_t* counter_t; - -counter_t init_counters(const int nb_perf, const __u32 *types, const __u64 *names); -void clean_counters(counter_t fd); -void start_counters(counter_t fd); -void reset_counters(counter_t fd); -void get_counters(counter_t fd, uint64_t *values); +void show_all_counters(); diff --git a/counters_individual.c b/counters_individual.c index fac60290570139d5439b07b7cad9c31eac6bdf28..79533ff756fc5f5ec92780748757451ebea2d922 100644 --- a/counters_individual.c +++ b/counters_individual.c @@ -28,17 +28,58 @@ #include <asm/unistd.h> #include <stdint.h> -#include "counters.h" - struct _counter_t { int nbcores; int nbperf; int **counters; + uint64_t *counters_values; + uint64_t *tmp_counters_values; + + int* perf_indexes; + }; - -static long -perf_event_open(struct perf_event_attr *hw_event, pid_t pid, - int cpu, int group_fd, unsigned long flags) { +typedef struct _counter_t* counter_t; + +#include "counters_option.h" + +void show_all_counters() { + for(int i=0; i<nb_counter_option;i++) + printf("%s\n", perf_static_info[i].name); + +} + +void perf_type_key(__u32 **perf_type, __u64 **perf_key, int *indexes, int nb){ + *perf_type = malloc(nb*sizeof(__u32)); + *perf_key = malloc(nb*sizeof(__u64)); + for(int i=0; i<nb; i++) { + (*perf_key)[i] = perf_static_info[indexes[i]].perf_key; + (*perf_type)[i] = perf_static_info[indexes[i]].perf_type; + } +} +void perf_event_list(char *perf_string, int *nb_perf, int **perf_indexes) { + char *token; + *nb_perf=0; + *perf_indexes=NULL; + while((token=strtok(perf_string, ",")) != NULL) { + perf_string = NULL; + int i; + for(i=0; i<nb_counter_option; i++) { + if(strcmp(perf_static_info[i].name, token) == 0) { + (*nb_perf)++; + (*perf_indexes) = realloc(*perf_indexes, sizeof(int)*(*nb_perf)); + (*perf_indexes)[*nb_perf-1]=i; + break; + } + } + if(i == nb_counter_option) { + fprintf(stderr, "Unknown performance counter: %s\n", token); + exit(EXIT_FAILURE); + } + } +} + +static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid, + int cpu, int group_fd, unsigned long flags) { long res = syscall(__NR_perf_event_open, hw_event, pid, cpu, group_fd, flags); if (res == -1) { perror("perf_event_open"); @@ -48,7 +89,7 @@ perf_event_open(struct perf_event_attr *hw_event, pid_t pid, return res; } -counter_t init_counters(const int nb_perf, const __u32 *types, const __u64 *names) { +counter_t _init_counters(const int nb_perf, const __u32 *types, const __u64 *names) { struct perf_event_attr pe; unsigned int nbcores = sysconf(_SC_NPROCESSORS_ONLN); memset(&pe, 0, sizeof(struct perf_event_attr)); @@ -71,13 +112,18 @@ counter_t init_counters(const int nb_perf, const __u32 *types, const __u64 *name return counters; } -void clean_counters(counter_t counters) { +void clean_counters(void *ptr) { + counter_t counters = (counter_t) ptr; for(int counter=0; counter<counters->nbperf; counter++) { for(int core=0; core<counters->nbcores; core++) close(counters->counters[counter][core]); free(counters->counters[counter]); } free(counters->counters); + free(counters->counters_values); + free(counters->tmp_counters_values); + free(counters->perf_indexes); + free(counters); } @@ -86,25 +132,70 @@ void start_counters(counter_t counters) { for(int core=0; core<counters->nbcores; core++) ioctl(counters->counters[counter][core], PERF_EVENT_IOC_ENABLE, 0); } + void reset_counters(counter_t counters) { for(int counter=0; counter<counters->nbperf; counter++) for(int core=0; core<counters->nbcores; core++) ioctl(counters->counters[counter][core], PERF_EVENT_IOC_RESET, 0); } -void get_counters(counter_t counters, uint64_t *values) { - //memset(values, 0, nb_perf*sizeof(long long)); +void _get_counters(counter_t counters, uint64_t *values) { for(int i=0; i<counters->nbperf; i++) { uint64_t accu=0; uint64_t count=0; for (int core=0; core<counters->nbcores; core++) { if (-1 == read(counters->counters[i][core], &count, sizeof(uint64_t))) { - fprintf(stderr, "PB Lecture resultat"); + fprintf(stderr, "Cannot read result"); exit(EXIT_FAILURE); } accu += count; } values[i] = accu; } - //reset_counters(counters); +} + + + + + + +unsigned int init_counters(char* args, void **state) { + int nb_perf; + int* perf_indexes=NULL; + + perf_event_list(args, &nb_perf, &perf_indexes); + + __u32* perf_type; + __u64* perf_key; + perf_type_key(&perf_type, &perf_key, perf_indexes, nb_perf); + counter_t fd = _init_counters(nb_perf, perf_type, perf_key); + free(perf_type); + free(perf_key); + + fd->perf_indexes = perf_indexes; + fd->counters_values = malloc(nb_perf*sizeof(uint64_t)); + fd->tmp_counters_values = malloc(nb_perf*sizeof(uint64_t)); + start_counters(fd); + _get_counters(fd, fd->counters_values); + *state = (void*) fd; + + return nb_perf; +} + +unsigned int get_counters(uint64_t* results, void*ptr) { + counter_t state = (counter_t) ptr; + +_get_counters(state, state->tmp_counters_values); + for(int i=0; i<state->nbperf; i++) + results[i] = state->tmp_counters_values[i] - state->counters_values[i]; + + memcpy(state->counters_values, state->tmp_counters_values, state->nbperf * sizeof(uint64_t)); + return state->nbperf; +} + +void label_counters(char **labels, void*ptr) { + counter_t state = (counter_t) ptr; + for(int i=0; i<state->nbperf;i++) + labels[i] = perf_static_info[state->perf_indexes[i]].name; + } diff --git a/infiniband.c b/infiniband.c index fb8928c4a6e68f6fce1badd09e4061d9f9c678a0..318a9e4f0a9f1b8051454bdd4c455b8a0b80e9ca 100644 --- a/infiniband.c +++ b/infiniband.c @@ -66,21 +66,3 @@ unsigned int init_infiniband(char* infi_path, void**ptr) { return 4; } - -/* void get_network(long long* results, char** sources) { */ -/* if(sources==NULL) */ -/* return; */ -/* for(int i=0; i<4; i++){ */ -/* FILE* f = fopen(sources[i], "rb"); */ -/* fscanf(f, "%lld", &results[i]); */ -/* fclose(f); */ -/* } */ -/* } */ - -/* void clean_network(char **sources) { */ -/* if(sources==NULL) */ -/* return; */ -/* for(int i=0;i<4;i++) */ -/* free(sources[i]); */ -/* free(sources); */ -/* } */ diff --git a/mojitos.c b/mojitos.c index a10cd47c009e2a4c7166b3ee7100dc37f3ddd44f..b72e2b72db770f25b4e47189ed924a66423fccb2 100644 --- a/mojitos.c +++ b/mojitos.c @@ -20,12 +20,7 @@ #include <stdlib.h> #include <stdio.h> -#include <asm/unistd.h> -#include <sys/stat.h> -#include <fcntl.h> #include <time.h> -#include <string.h> -#include <getopt.h> #include <signal.h> #include <inttypes.h> #include <unistd.h> @@ -36,53 +31,9 @@ #include "infiniband.h" #include "load.h" -#include "counters_option.h" -void show_all_counters() { - for(int i=0; i<nb_counter_option;i++) - printf("%s\n", perf_static_info[i].name); - -} -int nb_perf = 5; -int* perf_indexes=NULL; -// const char* perf_names[5] = {"instructions", "cachemisses", "pagefaults", "branchmisses", "cachmiss"}; -// const __u32 perf_type[5] = {PERF_TYPE_HARDWARE,PERF_TYPE_HARDWARE,PERF_TYPE_SOFTWARE, PERF_TYPE_HARDWARE, PERF_TYPE_HW_CACHE}; -// const __u64 perf_key[5] = {PERF_COUNT_HW_INSTRUCTIONS, PERF_COUNT_HW_CACHE_MISSES, -// PERF_COUNT_SW_PAGE_FAULTS,PERF_COUNT_HW_BRANCH_MISSES, -// PERF_COUNT_HW_CACHE_LL}; - -void perf_type_key(__u32 **perf_type, __u64 **perf_key, int *indexes, int nb){ - *perf_type = malloc(nb*sizeof(__u32)); - *perf_key = malloc(nb*sizeof(__u64)); - for(int i=0; i<nb; i++) { - (*perf_key)[i] = perf_static_info[indexes[i]].perf_key; - (*perf_type)[i] = perf_static_info[indexes[i]].perf_type; - } -} -void perf_event_list(char *perf_string, int *nb_perf, int **perf_indexes) { - char *token; - *nb_perf=0; - *perf_indexes=NULL; - while((token=strtok(perf_string, ",")) != NULL) { - perf_string = NULL; - int i; - for(i=0; i<nb_counter_option; i++) { - if(strcmp(perf_static_info[i].name, token) == 0) { - (*nb_perf)++; - (*perf_indexes) = realloc(*perf_indexes, sizeof(int)*(*nb_perf)); - (*perf_indexes)[*nb_perf-1]=i; - break; - } - } - if(i == nb_counter_option) { - fprintf(stderr, "Unknown performance counter: %s\n", token); - exit(EXIT_FAILURE); - } - } -} - void usage(char** argv) { printf("Usage : %s [-t time] [-f freq] [-r] [-p perf_list] [-l] [-u] [-c] [-d network_device] [-i infiniband_path] [-o logfile] [-e command arguments...]\n", argv[0]); printf("if time==0 then loops infinitively\n"); @@ -149,7 +100,6 @@ int main(int argc, char **argv) { int frequency=1; char **application = NULL; - int perf_mode = -1; int stat_mode = -1; if(argc==1) @@ -188,8 +138,7 @@ int main(int argc, char **argv) { signal(17,sighandler); break; case 'p': - perf_event_list(argv[optind], &nb_perf, &perf_indexes); - perf_mode=0; + add_source(init_counters, argv[optind], label_counters, get_counters, clean_counters); break; case 'r': add_source(init_rapl, NULL, label_rapl, get_rapl, clean_rapl); @@ -207,28 +156,10 @@ int main(int argc, char **argv) { usage(argv); } - // Hardware Performance Counters initialization - __u32* perf_type; - __u64* perf_key; - counter_t fd=0; - uint64_t *counter_values=NULL; - uint64_t *tmp_counter_values=NULL; - if(perf_mode==0) { - perf_type_key(&perf_type, &perf_key, perf_indexes, nb_perf); - fd = init_counters(nb_perf, perf_type, perf_key); - - counter_values = malloc(nb_perf*sizeof(uint64_t)); - tmp_counter_values = malloc(nb_perf*sizeof(uint64_t)); - - get_counters(fd, counter_values); - } struct timespec ts; struct timespec ts_ref; fprintf(output, "#timestamp "); - if(perf_mode==0) - for(int i=0; i<nb_perf;i++) - fprintf(output, "%s ", perf_static_info[perf_indexes[i]].name); for(int i=0; i<nb_sensors; i++) fprintf(output, "%s ", labels[i]); @@ -239,16 +170,11 @@ int main(int argc, char **argv) { fprintf(output, "\n"); unsigned long int stat_data=0; - if(perf_mode==0) - start_counters(fd); for (int temps = 0; temps <total_time*frequency; temps+=delta) { clock_gettime(CLOCK_MONOTONIC, &ts_ref); // Get Data - if(perf_mode==0) - get_counters(fd, tmp_counter_values); - unsigned int current = 0; for(int i=0; i<nb_sources; i++) current += getter[i](&values[current], states[i]); @@ -284,9 +210,6 @@ int main(int argc, char **argv) { // Treat Data fprintf(output, "%ld.%09ld ", ts_ref.tv_sec, ts_ref.tv_nsec); } - if(perf_mode==0) - for(int i=0; i<nb_perf;i++) - fprintf(output, "%" PRIu64 " ", tmp_counter_values[i]-counter_values[i]); for(int i=0; i<nb_sensors; i++) fprintf(output, "%" PRIu64 " ", values[i]); @@ -298,8 +221,6 @@ int main(int argc, char **argv) { if(application != NULL) break; - if(perf_mode==0) - memcpy(counter_values, tmp_counter_values, nb_perf*sizeof(uint64_t)); clock_gettime(CLOCK_MONOTONIC, &ts); usleep(1000*1000/frequency-(ts.tv_nsec/1000)%(1000*1000/frequency)); @@ -308,14 +229,6 @@ int main(int argc, char **argv) { for(int i=0; i<nb_sources;i++) cleaner[i](states[i]); - if(perf_mode==0){ - clean_counters(fd); - free(counter_values); - free(tmp_counter_values); - free(perf_type); - free(perf_key); - free(perf_indexes); - } if(nb_sources > 0) { free(getter); free(cleaner);