Skip to content
Snippets Groups Projects
Commit a3d535e3 authored by Georges Da Costa's avatar Georges Da Costa
Browse files

Finishes the refactoring

parent b1c5ab90
Branches
Tags
No related merge requests found
......@@ -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();
......@@ -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;
}
......@@ -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); */
/* } */
......@@ -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);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment