From 4cdee1503e9cc20ba12f9d882dbc5d1a8a103bbc Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Wed, 17 Jun 2009 18:15:16 +0200 Subject: [PATCH 01/62] communication techniques bench: refactoring (1) Main changes: * change library initialization: initialization is done with init_library once and init_thread_comm by each thread * cont is now directly accessed by main * list of struct communication_assoc -> array of struct thread_comm * struct communication_channel -> struct comm_channel --- .../include/asm_cache_comm.h | 17 ++--- .../include/common_comm.h | 9 +-- communication_techniques/src/asm_cache.c | 51 +++++++------ communication_techniques/src/common.c | 73 ++----------------- communication_techniques/src/main.c | 27 +++---- 5 files changed, 58 insertions(+), 119 deletions(-) diff --git a/communication_techniques/include/asm_cache_comm.h b/communication_techniques/include/asm_cache_comm.h index 16b8871..4c4b9eb 100644 --- a/communication_techniques/include/asm_cache_comm.h +++ b/communication_techniques/include/asm_cache_comm.h @@ -10,27 +10,24 @@ #define toString(x) doStringification(x) #define doStringification(x) #x -struct communication_channel +struct comm_channel { - void *buf[2 * BUF_SIZE / sizeof(void *)] __attribute__ ((aligned (CACHE_LINE_SIZE))); - int state __attribute__ ((aligned (CACHE_LINE_SIZE))); + volatile void *buf[2 * BUF_SIZE / sizeof(void *)] __attribute__ ((aligned (CACHE_LINE_SIZE))); + volatile int state __attribute__ ((aligned (CACHE_LINE_SIZE))); int idx __attribute__ ((aligned (CACHE_LINE_SIZE))); }; -struct communication_assoc +struct thread_comm { - struct communication_assoc *next; - struct communication_assoc *prev; - pthread_t tid; - struct communication_channel *channel; + struct comm_channel *channel; int receiver_idx; }; -extern struct communication_assoc assoc_root; +extern struct thread_comm *tcomms; __BEGIN_DECLS -struct communication_assoc *create_comm_assoc(void); +void init_thread_comm(void); static inline void send(void **addr) { asm volatile("mov %%gs:channel@NTPOFF + 2 *" toString(BUF_SIZE) " + " toString(CACHE_LINE_SIZE) ", %%eax\n\t" "mov %0, %%gs:channel@NTPOFF(%%eax)\n\t" diff --git a/communication_techniques/include/common_comm.h b/communication_techniques/include/common_comm.h index 2f5d17b..8e6d2e8 100644 --- a/communication_techniques/include/common_comm.h +++ b/communication_techniques/include/common_comm.h @@ -10,16 +10,13 @@ #define unlikely(x) __builtin_expect(!!(x), 0) extern volatile int cont; +extern long nb_prod; __BEGIN_DECLS -void add_sender(void); -void remove_sender(void); -volatile int *init_comm(void); -void reception(void (*)(void *)); +int init_library(void); +void reception(void (*)(volatile void *)); extern int swap_buffer; -void wait_initialization(void); -void discover_new_producers(void); __END_DECLS diff --git a/communication_techniques/src/asm_cache.c b/communication_techniques/src/asm_cache.c index f4fffb9..e6903b1 100644 --- a/communication_techniques/src/asm_cache.c +++ b/communication_techniques/src/asm_cache.c @@ -7,17 +7,24 @@ #include -__thread struct communication_channel channel; +__thread struct comm_channel channel; -struct communication_assoc *create_comm_assoc(void) +void init_thread_comm(void) { - struct communication_assoc *assoc; + static int i = 0; + static pthread_mutex_t i_lock = PTHREAD_MUTEX_INITIALIZER; + int i_local; - assoc = (struct communication_assoc *) malloc(sizeof(struct communication_assoc)); - assoc->tid = pthread_self(); - assoc->receiver_idx = 0; - assoc->channel = &channel; - return assoc; + pthread_mutex_lock(&i_lock); + i_local = i; + pthread_mutex_unlock(&i_lock); + tcomms[i].receiver_idx = 0; + tcomms[i].channel = &channel; + tcomms[i].channel->state = 0; + tcomms[i].channel->idx = 0; + pthread_mutex_lock(&i_lock); + i++; + pthread_mutex_unlock(&i_lock); } char *dstr="buffer transition\n"; @@ -35,21 +42,18 @@ void _swap_buffer() : : "m"(dstr)); } -void reception(void (*on_receive)(void *)) +void reception(void (*on_receive)(volatile void *)) { - wait_initialization(); /* printf("Activate the consumer...\n"); */ - while(cont) + while (cont) { - struct communication_assoc *cur; + int i; - discover_new_producers(); - cur = assoc_root.next; - while(cur != &assoc_root) + for (i = 0; i < nb_prod; i++) { - struct communication_channel *channel = cur->channel; - if(channel->state) + if(tcomms[i].channel->state) { + int j, n; /* * cur->receiver_idx point to the last cache * line we have read. We go to the next cache @@ -59,14 +63,13 @@ void reception(void (*on_receive)(void *)) * line we correct the pointer to point to * the first one (this is done by the modulo) */ - int i = cur->receiver_idx; - int n = cur->receiver_idx + (BUF_SIZE / sizeof(void *)); - cur->receiver_idx = n % ((2 * BUF_SIZE) / sizeof(void *)); - for(; ibuf[i]); - channel->state = 0; + j = tcomms[i].receiver_idx; + n = tcomms[i].receiver_idx + (BUF_SIZE / sizeof(void *)); + tcomms[i].receiver_idx = n % ((2 * BUF_SIZE) / sizeof(void *)); + for(; jbuf[j]); + tcomms[i].channel->state = 0; } - cur = cur->next; } } } diff --git a/communication_techniques/src/common.c b/communication_techniques/src/common.c index febfa5d..4c41510 100644 --- a/communication_techniques/src/common.c +++ b/communication_techniques/src/common.c @@ -7,75 +7,16 @@ #include -struct communication_assoc assoc_root; -static pthread_mutex_t assoc_lock = PTHREAD_MUTEX_INITIALIZER; -static struct communication_assoc assoc_tmp; -static volatile int init = 0; +struct thread_comm *tcomms; volatile int cont = 1; -void initialize_library(void) +int init_library() { - assoc_tmp.prev = &assoc_tmp; - assoc_tmp.next = &assoc_tmp; - assoc_root.prev = &assoc_root; - assoc_root.next = &assoc_root; -} - -volatile int *init_comm(void) -{ - return &cont; -} - -void wait_initialization(void) -{ - while (!init); -} - -void add_sender(void) -{ - struct communication_assoc *assoc; - - assoc = create_comm_assoc(); - pthread_mutex_lock(&assoc_lock); - if (!init) + tcomms = (struct thread_comm *) malloc(nb_prod * sizeof(struct thread_comm)); + if (tcomms == NULL) { - initialize_library(); - init = 1; - } - assoc->next = assoc_tmp.next; - assoc_tmp.next->prev = assoc; - assoc->prev = &assoc_tmp; - assoc_tmp.next = assoc; - pthread_mutex_unlock(&assoc_lock); -} - -void remove_sender() -{ - printf("remove_communication_channel: Not yet implemented\n"); -} - -void discover_new_producers(void) -{ - /* If there is some new thread for the write barrier */ - if(&assoc_tmp != assoc_tmp.next) - { - /* printf("Adding a new set of producers\n"); */ - pthread_mutex_lock(&assoc_lock); - /* - * list in assoc_tmp is inserted between assoc_root - * and the first elements of assoc_root list - */ - assoc_root.next->prev = assoc_tmp.prev; - assoc_tmp.prev->next = assoc_root.next; - assoc_root.next = assoc_tmp.next; - assoc_root.next->prev = &assoc_root; - /* - * assoc_tmp temporary list has been copied in - * assoc_root list. assoc_tmp is now alone and so - * double linked to itself - */ - assoc_tmp.prev = &assoc_tmp; - assoc_tmp.next = &assoc_tmp; - pthread_mutex_unlock(&assoc_lock); + fprintf(stderr, "Failed to allocate %lu bytes needed by the library to work\n", nb_prod * sizeof(struct thread_comm)); + return -1; } + return 0; } diff --git a/communication_techniques/src/main.c b/communication_techniques/src/main.c index fa34f72..7fc9685 100644 --- a/communication_techniques/src/main.c +++ b/communication_techniques/src/main.c @@ -16,7 +16,7 @@ #include static long nb_cache_lines = 0; -static long nb_prod = 0; +long nb_prod = 0; static long size_buf = 1; static char *calculation_lib = NULL; static int shared = 0; @@ -145,13 +145,12 @@ int analyse_options(int argc, char *argv[]) return 0; } -void *producer(void *cont_ptr_void) +void *producer(void *unused) { int i, j; void *k; - volatile int *cont; - cont = *((volatile int **) cont_ptr_void); + init_thread_comm(); if (shared) { pthread_t tid; @@ -166,9 +165,7 @@ void *producer(void *cont_ptr_void) return NULL; } } - printf("Registering: %p !\n", (void*) pthread_self()); - add_sender(); - k = cont_ptr_void; + k = (void *) 0x6384923; if (initialize_papi() != -1) { for(i = 0; i < nb_cache_lines; i++) { @@ -179,21 +176,20 @@ void *producer(void *cont_ptr_void) print_results(); } printf("[%p] Producer finished !\n", (void*) pthread_self()); - remove_sender(); /* * When a producer end its thread-local storage vanished. Thus, * producers must finish only after consumer has stopped using them */ pthread_mutex_lock(&mutex_cons_has_finished); if (++producers_ended == nb_prod) - *cont = 0; + cont = 0; if (!consumer_has_finished) pthread_cond_wait(&cond_cons_has_finished, &mutex_cons_has_finished); pthread_mutex_unlock(&mutex_cons_has_finished); return NULL; } -void onMessage(void *val) +void onMessage(volatile void *val) { //printf("Receive value: %p\n", (void *) val); } @@ -225,16 +221,21 @@ void *receptor(void *a) int main(int argc, char *argv[]) { int i; - volatile int *cont; void *return_value; pthread_t *tid; if (analyse_options(argc, argv)) return EXIT_FAILURE; + if (init_library()) + return EXIT_FAILURE; tid = (pthread_t *) malloc((nb_prod + 1) * sizeof(pthread_t)); - cont = init_comm(); + if (tid == NULL) + { + fprintf(stderr, "Failed to allocate %lu bytes needed for thread creation\n", (nb_prod + 1) * sizeof(pthread_t)); + return EXIT_FAILURE; + } for(i = 0; i < nb_prod; i++) - pthread_create(&tid[i], NULL, producer, &cont); + pthread_create(&tid[i], NULL, producer, NULL); pthread_create(&tid[i], NULL, receptor, NULL); for(i = 0; i < nb_prod; i++) pthread_join(tid[i], &return_value); From b522ce373f6b6946010fca21dc5a73eeb0fac11a Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Wed, 17 Jun 2009 18:22:03 +0200 Subject: [PATCH 02/62] communication techniques bench: typo --- communication_techniques/include/asm_cache_comm.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/communication_techniques/include/asm_cache_comm.h b/communication_techniques/include/asm_cache_comm.h index 4c4b9eb..47ac2db 100644 --- a/communication_techniques/include/asm_cache_comm.h +++ b/communication_techniques/include/asm_cache_comm.h @@ -28,7 +28,8 @@ extern struct thread_comm *tcomms; __BEGIN_DECLS void init_thread_comm(void); -static inline void send(void **addr) { +static inline void send(void **addr) +{ asm volatile("mov %%gs:channel@NTPOFF + 2 *" toString(BUF_SIZE) " + " toString(CACHE_LINE_SIZE) ", %%eax\n\t" "mov %0, %%gs:channel@NTPOFF(%%eax)\n\t" "addl $4, %%eax\n\t" From ebbb03f65e3b268b421cc61eeff86d6803a21e8d Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Wed, 17 Jun 2009 19:12:22 +0200 Subject: [PATCH 03/62] communication techniques bench: BUGFIX * -s really make the threads to be on a shared cache --- communication_techniques/src/main.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/communication_techniques/src/main.c b/communication_techniques/src/main.c index 7fc9685..753c87d 100644 --- a/communication_techniques/src/main.c +++ b/communication_techniques/src/main.c @@ -165,6 +165,20 @@ void *producer(void *unused) return NULL; } } + else + { + pthread_t tid; + cpu_set_t cpuset; + + tid = pthread_self(); + CPU_ZERO(&cpuset); + CPU_SET(2, &cpuset); + if (pthread_setaffinity_np(tid, sizeof(cpu_set_t), &cpuset)) + { + perror("pthread_setaffinity_np"); + return NULL; + } + } k = (void *) 0x6384923; if (initialize_papi() != -1) { @@ -203,7 +217,7 @@ void *receptor(void *a) tid = pthread_self(); CPU_ZERO(&cpuset); - CPU_SET(1, &cpuset); + CPU_SET(0, &cpuset); if (pthread_setaffinity_np(tid, sizeof(cpu_set_t), &cpuset)) { perror("pthread_setaffinity_np"); From b5575aa710c507d7b48d29cbe5a819e5f5000747 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Wed, 17 Jun 2009 19:18:38 +0200 Subject: [PATCH 04/62] communication techniques bench: add c_cache_comm --- .../include/c_cache_comm.h | 45 ++++++++++++++ communication_techniques/src/c_cache.c | 62 +++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 communication_techniques/include/c_cache_comm.h create mode 100644 communication_techniques/src/c_cache.c diff --git a/communication_techniques/include/c_cache_comm.h b/communication_techniques/include/c_cache_comm.h new file mode 100644 index 0000000..68750a7 --- /dev/null +++ b/communication_techniques/include/c_cache_comm.h @@ -0,0 +1,45 @@ +#ifndef _SPECIFIC_COMM_H_ +#define _SPECIFIC_COMM_H_ 1 + +#include + +/* Non standard include */ +#include + +/* This is not an error, we need this two-macro system */ +#define toString(x) doStringification(x) +#define doStringification(x) #x + +struct comm_channel +{ + volatile void *buf[2 * BUF_SIZE / sizeof(void *)] __attribute__ ((aligned (CACHE_LINE_SIZE))); + volatile int state __attribute__ ((aligned (CACHE_LINE_SIZE))); + int idx __attribute__ ((aligned (CACHE_LINE_SIZE))); +}; + +struct thread_comm +{ + struct comm_channel *channel; + int receiver_idx; +}; + +extern struct thread_comm *tcomms; +extern __thread struct comm_channel channel; + +__BEGIN_DECLS + +void init_thread_comm(void); +static inline void send(void **addr) +{ + channel.buf[channel.idx++] = addr; + channel.idx %= 2 * BUF_SIZE / sizeof(void *); + if (!(channel.idx % (BUF_SIZE / sizeof(void *)))) + { + while (channel.state); + channel.state = 1; + } +} + +__END_DECLS + +#endif diff --git a/communication_techniques/src/c_cache.c b/communication_techniques/src/c_cache.c new file mode 100644 index 0000000..0292594 --- /dev/null +++ b/communication_techniques/src/c_cache.c @@ -0,0 +1,62 @@ +#include +#include +#include + +/* Non standard include */ +#include +#include + + +__thread struct comm_channel channel; + +void init_thread_comm(void) +{ + static int i = 0; + static pthread_mutex_t i_lock = PTHREAD_MUTEX_INITIALIZER; + int i_local; + + pthread_mutex_lock(&i_lock); + i_local = i; + pthread_mutex_unlock(&i_lock); + tcomms[i].receiver_idx = 0; + tcomms[i].channel = &channel; + tcomms[i].channel->state = 0; + tcomms[i].channel->idx = 0; + pthread_mutex_lock(&i_lock); + i++; + pthread_mutex_unlock(&i_lock); +} + +char *dstr="buffer transition\n"; + +void reception(void (*on_receive)(volatile void *)) +{ + /* printf("Activate the consumer...\n"); */ + while (cont) + { + int i; + + for (i = 0; i < nb_prod; i++) + { + if(tcomms[i].channel->state) + { + int j, n; + /* + * cur->receiver_idx point to the last cache + * line we have read. We go to the next cache + * line "+ (CACHE_LINE_SIZE >> 2)" (because + * the line is full of integer (2^2 octets) + * and then if we are after the second cache + * line we correct the pointer to point to + * the first one (this is done by the modulo) + */ + j = tcomms[i].receiver_idx; + n = tcomms[i].receiver_idx + (BUF_SIZE / sizeof(void *)); + tcomms[i].receiver_idx = n % ((2 * BUF_SIZE) / sizeof(void *)); + for(; jbuf[j]); + tcomms[i].channel->state = 0; + } + } + } +} From 274f3cfd1bc2e5d763ce4744476ae44aa1358074 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Thu, 18 Jun 2009 14:48:07 +0200 Subject: [PATCH 05/62] communication techniques bench: refactoring (2) Main changes: * Better separation of what is common from what is specific to a communication technique * Consumer wait initialization of all producer threads --- .../include/asm_cache_comm.h | 12 +++--- .../include/c_cache_comm.h | 6 +-- .../include/{common_comm.h => commtech.h} | 10 ++--- communication_techniques/include/fake_comm.h | 19 +++----- .../include/jikes_barrier_comm.h | 24 +++++------ communication_techniques/include/pipe_comm.h | 19 +++----- .../include/private_common.h | 10 +++++ .../include/shared_mem_comm.h | 21 ++++----- .../include/shared_mem_opt_comm.h | 21 ++++----- communication_techniques/src/asm_cache.c | 34 +++++++-------- communication_techniques/src/c_cache.c | 34 +++++++-------- communication_techniques/src/common.c | 43 ++++++++++++++++++- communication_techniques/src/fake.c | 12 ++---- communication_techniques/src/jikes_barrier.c | 12 +++--- communication_techniques/src/main.c | 10 ++--- communication_techniques/src/pipe.c | 43 +++++++++++-------- communication_techniques/src/shared_mem.c | 37 +++++++--------- communication_techniques/src/shared_mem_opt.c | 43 ++++++++----------- 18 files changed, 207 insertions(+), 203 deletions(-) rename communication_techniques/include/{common_comm.h => commtech.h} (65%) create mode 100644 communication_techniques/include/private_common.h diff --git a/communication_techniques/include/asm_cache_comm.h b/communication_techniques/include/asm_cache_comm.h index 47ac2db..d6b7c95 100644 --- a/communication_techniques/include/asm_cache_comm.h +++ b/communication_techniques/include/asm_cache_comm.h @@ -1,15 +1,15 @@ #ifndef _SPECIFIC_COMM_H_ #define _SPECIFIC_COMM_H_ 1 -#include - /* Non standard include */ -#include +#include /* This is not an error, we need this two-macro system */ #define toString(x) doStringification(x) #define doStringification(x) #x +__BEGIN_DECLS + struct comm_channel { volatile void *buf[2 * BUF_SIZE / sizeof(void *)] __attribute__ ((aligned (CACHE_LINE_SIZE))); @@ -21,13 +21,13 @@ struct thread_comm { struct comm_channel *channel; int receiver_idx; + int unused; }; extern struct thread_comm *tcomms; +extern int swap_buffer; -__BEGIN_DECLS - -void init_thread_comm(void); +void init_thread_comm(struct thread_comm *); static inline void send(void **addr) { asm volatile("mov %%gs:channel@NTPOFF + 2 *" toString(BUF_SIZE) " + " toString(CACHE_LINE_SIZE) ", %%eax\n\t" diff --git a/communication_techniques/include/c_cache_comm.h b/communication_techniques/include/c_cache_comm.h index 68750a7..49d39af 100644 --- a/communication_techniques/include/c_cache_comm.h +++ b/communication_techniques/include/c_cache_comm.h @@ -1,10 +1,8 @@ #ifndef _SPECIFIC_COMM_H_ #define _SPECIFIC_COMM_H_ 1 -#include - /* Non standard include */ -#include +#include /* This is not an error, we need this two-macro system */ #define toString(x) doStringification(x) @@ -28,7 +26,7 @@ extern __thread struct comm_channel channel; __BEGIN_DECLS -void init_thread_comm(void); +void init_thread_comm(struct thread_comm *); static inline void send(void **addr) { channel.buf[channel.idx++] = addr; diff --git a/communication_techniques/include/common_comm.h b/communication_techniques/include/commtech.h similarity index 65% rename from communication_techniques/include/common_comm.h rename to communication_techniques/include/commtech.h index 8e6d2e8..539c977 100644 --- a/communication_techniques/include/common_comm.h +++ b/communication_techniques/include/commtech.h @@ -1,7 +1,5 @@ -#ifndef _COMMON_COMM_H_ -#define _COMMON_COMM_H_ 1 - -#include +#ifndef _COMMTECH_H_ +#define _COMMTECH_H_ 1 #define CACHE_LINE_SIZE 128 #define BUF_SIZE CACHE_LINE_SIZE @@ -15,8 +13,8 @@ extern long nb_prod; __BEGIN_DECLS int init_library(void); -void reception(void (*)(volatile void *)); -extern int swap_buffer; +void init_producer_thread(void); +void reception(void (*)(void *)); __END_DECLS diff --git a/communication_techniques/include/fake_comm.h b/communication_techniques/include/fake_comm.h index 90c2e95..fad7f07 100644 --- a/communication_techniques/include/fake_comm.h +++ b/communication_techniques/include/fake_comm.h @@ -1,25 +1,18 @@ -#ifndef __COMM_H_ -#define __COMM_H_ 1 - -#include - -/* Non standard include */ -#include +#ifndef _SPECIFIC_COMM_H_ +#define _SPECIFIC_COMM_H_ 1 #define FAKE_NURSERY_START 1 -struct communication_assoc +struct thread_comm { - struct communication_assoc *next; - struct communication_assoc *prev; - pthread_t tid; + int unused; }; -extern struct communication_assoc assoc_root; +extern struct thread_comm *tcomms; __BEGIN_DECLS -struct communication_assoc *create_comm_assoc(void); +void init_thread_comm(struct thread_comm *); static inline void send(void **addr) { static __thread void **store_var = NULL; store_var = addr; diff --git a/communication_techniques/include/jikes_barrier_comm.h b/communication_techniques/include/jikes_barrier_comm.h index 536060e..4cf541d 100644 --- a/communication_techniques/include/jikes_barrier_comm.h +++ b/communication_techniques/include/jikes_barrier_comm.h @@ -1,32 +1,28 @@ -#ifndef __COMM_H_ -#define __COMM_H_ 1 +#ifndef _SPECIFIC_COMM_H_ +#define _SPECIFIC_COMM_H_ 1 #include -/* Non standard include */ -#include - #define FAKE_NURSERY_START 1 -#define REALLY_FAKE_NURSERY_START ((uintptr_t) -1) +#define ANOTHER_FAKE_NURSERY_START ((uintptr_t) -1) -struct communication_assoc +struct thread_comm { - struct communication_assoc *next; - struct communication_assoc *prev; - pthread_t tid; + int unused; }; -extern struct communication_assoc assoc_root; +extern struct thread_comm *tcomms; __BEGIN_DECLS -struct communication_assoc *create_comm_assoc(void); +void init_thread_comm(struct thread_comm *); void insert(void *); -static inline void send(void **addr) { +static inline void send(void **addr) +{ void *ptd_addr; ptd_addr = *addr; /* NOTE: Not done in real jikes barrier */ - if (!((uintptr_t) addr >= REALLY_FAKE_NURSERY_START) && ((uintptr_t) ptd_addr >= FAKE_NURSERY_START)) + if (!((uintptr_t) addr >= ANOTHER_FAKE_NURSERY_START) && ((uintptr_t) ptd_addr >= FAKE_NURSERY_START)) insert(addr); } diff --git a/communication_techniques/include/pipe_comm.h b/communication_techniques/include/pipe_comm.h index fd2d49e..620000a 100644 --- a/communication_techniques/include/pipe_comm.h +++ b/communication_techniques/include/pipe_comm.h @@ -1,31 +1,22 @@ -#ifndef __COMM_H_ -#define __COMM_H_ 1 +#ifndef _SPECIFIC_COMM_H_ +#define _SPECIFIC_COMM_H_ 1 -#include #include -/* Non standart include */ -#include - #define READ_IDX 0 #define WRITE_IDX 1 -struct communication_assoc +struct thread_comm { - struct communication_assoc *next; - struct communication_assoc *prev; - pthread_t tid; int *pipefd; - struct communication_channel *channel; - int receiver_idx; }; __BEGIN_DECLS extern __thread int pipefd[]; -extern struct communication_assoc assoc_root; +extern struct thread_comm *tcomms; -struct communication_assoc *create_comm_assoc(void); +void init_thread_comm(struct thread_comm *); static inline void send(void **addr) { write(pipefd[WRITE_IDX], &addr, sizeof(void *)); } diff --git a/communication_techniques/include/private_common.h b/communication_techniques/include/private_common.h new file mode 100644 index 0000000..ab27b64 --- /dev/null +++ b/communication_techniques/include/private_common.h @@ -0,0 +1,10 @@ +#ifndef _PRIVATE_COMMON_H_ +#define _PRIVATE_COMMON_H_ 1 + +__BEGIN_DECLS + +void wait_initialization(void); + +__END_DECLS + +#endif diff --git a/communication_techniques/include/shared_mem_comm.h b/communication_techniques/include/shared_mem_comm.h index 8bc88b9..f9d4214 100644 --- a/communication_techniques/include/shared_mem_comm.h +++ b/communication_techniques/include/shared_mem_comm.h @@ -1,33 +1,28 @@ -#ifndef __COMM_H_ -#define __COMM_H_ 1 - -#include +#ifndef _SPECIFIC_COMM_H_ +#define _SPECIFIC_COMM_H_ 1 /* Non standard include */ -#include +#include #define SHARED_SPACE_SIZE (2 * BUF_SIZE) #define SHARED_SPACE_VOIDPTR (SHARED_SPACE_SIZE / sizeof(void *)) -struct communication_assoc +struct thread_comm { - struct communication_assoc *next; - struct communication_assoc *prev; - pthread_t tid; - void **shared_space; + volatile void **shared_space; volatile int *cons_idx; volatile int *prod_idx; }; -extern struct communication_assoc assoc_root; +extern struct thread_comm *tcomms; __BEGIN_DECLS -extern __thread void **shared_space; +extern __thread volatile void **shared_space; extern __thread volatile int prod_idx; extern __thread volatile int cons_idx; -struct communication_assoc *create_comm_assoc(void); +void init_thread_comm(struct thread_comm *); static inline void send(void **addr) { while ((prod_idx + 1) % SHARED_SPACE_VOIDPTR == cons_idx); shared_space[prod_idx] = addr; diff --git a/communication_techniques/include/shared_mem_opt_comm.h b/communication_techniques/include/shared_mem_opt_comm.h index 5cabe9c..6126004 100644 --- a/communication_techniques/include/shared_mem_opt_comm.h +++ b/communication_techniques/include/shared_mem_opt_comm.h @@ -1,33 +1,28 @@ -#ifndef __COMM_H_ -#define __COMM_H_ 1 - -#include +#ifndef _SPECIFIC_COMM_H_ +#define _SPECIFIC_COMM_H_ 1 /* Non standard include */ -#include +#include #define SHARED_SPACE_SIZE (2 * BUF_SIZE) #define SHARED_SPACE_VOIDPTR (SHARED_SPACE_SIZE / sizeof(void *)) -struct communication_assoc +struct thread_comm { - struct communication_assoc *next; - struct communication_assoc *prev; - pthread_t tid; - void **shared_space; + volatile void **shared_space; volatile int *cons_idx; volatile int *prod_idx; }; -extern struct communication_assoc assoc_root; +extern struct thread_comm *tcomms; __BEGIN_DECLS -extern __thread void **shared_space; +extern __thread volatile void **shared_space; extern __thread volatile int prod_idx; extern __thread volatile int cons_idx; -struct communication_assoc *create_comm_assoc(void); +void init_thread_comm(struct thread_comm *); static inline void send(void **addr) { static __thread int local_cons_idx = 0; diff --git a/communication_techniques/src/asm_cache.c b/communication_techniques/src/asm_cache.c index e6903b1..bf4589a 100644 --- a/communication_techniques/src/asm_cache.c +++ b/communication_techniques/src/asm_cache.c @@ -3,28 +3,19 @@ #include /* Non standard include */ -#include +#include +#include #include __thread struct comm_channel channel; -void init_thread_comm(void) +void init_thread_comm(struct thread_comm *comm) { - static int i = 0; - static pthread_mutex_t i_lock = PTHREAD_MUTEX_INITIALIZER; - int i_local; - - pthread_mutex_lock(&i_lock); - i_local = i; - pthread_mutex_unlock(&i_lock); - tcomms[i].receiver_idx = 0; - tcomms[i].channel = &channel; - tcomms[i].channel->state = 0; - tcomms[i].channel->idx = 0; - pthread_mutex_lock(&i_lock); - i++; - pthread_mutex_unlock(&i_lock); + comm->receiver_idx = 0; + comm->channel = &channel; + comm->channel->state = 0; + comm->channel->idx = 0; } char *dstr="buffer transition\n"; @@ -42,8 +33,9 @@ void _swap_buffer() : : "m"(dstr)); } -void reception(void (*on_receive)(volatile void *)) +void reception(void (*on_receive)(void *)) { + wait_initialization(); /* printf("Activate the consumer...\n"); */ while (cont) { @@ -67,7 +59,13 @@ void reception(void (*on_receive)(volatile void *)) n = tcomms[i].receiver_idx + (BUF_SIZE / sizeof(void *)); tcomms[i].receiver_idx = n % ((2 * BUF_SIZE) / sizeof(void *)); for(; jbuf[j]); + { + /* + * The behaviour of this is not documented but we know + * the values inside buf won't change during this affectation + */ + on_receive((void *) tcomms[i].channel->buf[j]); + } tcomms[i].channel->state = 0; } } diff --git a/communication_techniques/src/c_cache.c b/communication_techniques/src/c_cache.c index 0292594..42f081d 100644 --- a/communication_techniques/src/c_cache.c +++ b/communication_techniques/src/c_cache.c @@ -3,34 +3,26 @@ #include /* Non standard include */ -#include +#include +#include #include __thread struct comm_channel channel; -void init_thread_comm(void) +void init_thread_comm(struct thread_comm *comm) { - static int i = 0; - static pthread_mutex_t i_lock = PTHREAD_MUTEX_INITIALIZER; - int i_local; - - pthread_mutex_lock(&i_lock); - i_local = i; - pthread_mutex_unlock(&i_lock); - tcomms[i].receiver_idx = 0; - tcomms[i].channel = &channel; - tcomms[i].channel->state = 0; - tcomms[i].channel->idx = 0; - pthread_mutex_lock(&i_lock); - i++; - pthread_mutex_unlock(&i_lock); + comm->receiver_idx = 0; + comm->channel = &channel; + comm->channel->state = 0; + comm->channel->idx = 0; } char *dstr="buffer transition\n"; -void reception(void (*on_receive)(volatile void *)) +void reception(void (*on_receive)(void *)) { + wait_initialization(); /* printf("Activate the consumer...\n"); */ while (cont) { @@ -54,7 +46,13 @@ void reception(void (*on_receive)(volatile void *)) n = tcomms[i].receiver_idx + (BUF_SIZE / sizeof(void *)); tcomms[i].receiver_idx = n % ((2 * BUF_SIZE) / sizeof(void *)); for(; jbuf[j]); + { + /* + * The behaviour of this is not documented but we know + * the values inside buf won't change during this affectation + */ + on_receive((void *) tcomms[i].channel->buf[j]); + } tcomms[i].channel->state = 0; } } diff --git a/communication_techniques/src/common.c b/communication_techniques/src/common.c index 4c41510..3566dd5 100644 --- a/communication_techniques/src/common.c +++ b/communication_techniques/src/common.c @@ -5,12 +5,16 @@ /* Non standard include */ #include +#include struct thread_comm *tcomms; volatile int cont = 1; +static int init = 0; +static pthread_mutex_t init_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t init_cond = PTHREAD_COND_INITIALIZER; -int init_library() +int init_library(void) { tcomms = (struct thread_comm *) malloc(nb_prod * sizeof(struct thread_comm)); if (tcomms == NULL) @@ -20,3 +24,40 @@ int init_library() } return 0; } + +int get_thread_number(void) +{ + static int i = 0; + static pthread_mutex_t i_lock = PTHREAD_MUTEX_INITIALIZER; + int i_local; + + pthread_mutex_lock(&i_lock); + i_local = i; + i++; + pthread_mutex_unlock(&i_lock); + return i_local; +} + +void init_producer_thread(void) +{ + static int i = 0; + static pthread_mutex_t i_lock = PTHREAD_MUTEX_INITIALIZER; + int i_local; + + pthread_mutex_lock(&i_lock); + i_local = i; + i++; + pthread_mutex_unlock(&i_lock); + init_thread_comm(&tcomms[i_local]); + pthread_mutex_lock(&init_lock); + init = 1; + pthread_mutex_unlock(&init_lock); +} + +void wait_initialization(void) +{ + pthread_mutex_lock(&init_lock); + if (!init) + pthread_cond_wait(&init_cond, &init_lock); + pthread_mutex_unlock(&init_lock); +} diff --git a/communication_techniques/src/fake.c b/communication_techniques/src/fake.c index a47de81..68792f5 100644 --- a/communication_techniques/src/fake.c +++ b/communication_techniques/src/fake.c @@ -4,22 +4,18 @@ #include /* Non standard include */ -#include +#include +#include #include -struct communication_assoc *create_comm_assoc(void) +void init_thread_comm(struct thread_comm *comm) { - struct communication_assoc *assoc; - - assoc = (struct communication_assoc *) malloc(sizeof(struct communication_assoc)); - assoc->tid = pthread_self(); - return assoc; } void reception(void (*on_receive)(void *)) { - wait_initialization(); + wait_initialization(); /* Not needed but here for equity with others techniques */ /* printf("Activate the consumer...\n"); */ while (cont); } diff --git a/communication_techniques/src/jikes_barrier.c b/communication_techniques/src/jikes_barrier.c index 314b83e..e232797 100644 --- a/communication_techniques/src/jikes_barrier.c +++ b/communication_techniques/src/jikes_barrier.c @@ -4,7 +4,8 @@ #include /* Non standard include */ -#include +#include +#include #include @@ -32,18 +33,14 @@ static struct double_linked_list *global_head = NULL; static int bufsenqueued = 0; static unsigned int lock = 0; -struct communication_assoc *create_comm_assoc(void) +void init_thread_comm(struct thread_comm *comm) { - struct communication_assoc *assoc; void **new_buffer; new_buffer = (void **) malloc(BUFFER_SIZE); local_tail = new_buffer + (USABLE_BUFFER_BYTES - BYTES_IN_ADDRESS - (USABLE_BUFFER_BYTES % (1 << LOG_BYTES_IN_ADDRESS))) + BYTES_IN_ADDRESS; // The second parenthesis is equal to 0 local_tail_buffer_end = local_tail; - assoc = (struct communication_assoc *) malloc(sizeof(struct communication_assoc)); - assoc->tid = pthread_self(); - return assoc; } void set_next(struct double_linked_list *list, struct double_linked_list *next) @@ -169,7 +166,8 @@ void reception(void (*on_receive)(void *)) { struct double_linked_list *list_cur; void **buf_start, **buf_ptr; - wait_initialization(); + + wait_initialization(); /* Not needed but here for equity with others techniques */ /* printf("Activate the consumer...\n"); */ while (cont && (global_head == NULL)); if (!cont) diff --git a/communication_techniques/src/main.c b/communication_techniques/src/main.c index 753c87d..c26cd05 100644 --- a/communication_techniques/src/main.c +++ b/communication_techniques/src/main.c @@ -12,7 +12,7 @@ /* Non standards includes */ #include -#include +#include #include static long nb_cache_lines = 0; @@ -150,7 +150,7 @@ void *producer(void *unused) int i, j; void *k; - init_thread_comm(); + init_producer_thread(); if (shared) { pthread_t tid; @@ -183,8 +183,8 @@ void *producer(void *unused) if (initialize_papi() != -1) { for(i = 0; i < nb_cache_lines; i++) { - //printf("[%p] Send a new CACHE_LINE\n", (void *) pthread_self()); - for(j = 0; j < (CACHE_LINE_SIZE / sizeof(uintptr_t)); j++) + //printf("[%p] Send %d new CACHE_LINE\n", (void *) pthread_self(), BUF_SIZE / CACHE_LINE_SIZE); + for(j = 0; j < (BUF_SIZE / sizeof(uintptr_t)); j++) send(&k); } print_results(); @@ -203,7 +203,7 @@ void *producer(void *unused) return NULL; } -void onMessage(volatile void *val) +void onMessage(void *val) { //printf("Receive value: %p\n", (void *) val); } diff --git a/communication_techniques/src/pipe.c b/communication_techniques/src/pipe.c index d41b091..dbec091 100644 --- a/communication_techniques/src/pipe.c +++ b/communication_techniques/src/pipe.c @@ -2,46 +2,53 @@ #include #include #include +#include +#include /* Non standard include */ -#include +#include +#include #include __thread int pipefd[2]; -struct communication_assoc *create_comm_assoc(void) +void init_thread_comm(struct thread_comm *comm) { - struct communication_assoc *assoc; + int flags; pipe(pipefd); - assoc = (struct communication_assoc *) malloc(sizeof(struct communication_assoc)); - assoc->tid = pthread_self(); - assoc->pipefd = pipefd; - return assoc; + flags = fcntl(pipefd[READ_IDX], F_GETFL); + fcntl(pipefd[READ_IDX], F_SETFL, flags | O_NONBLOCK); + comm->pipefd = pipefd; } void reception(void (*on_receive)(void *)) { - wait_initialization(); + wait_initialization(); /* Not needed but here for equity with others techniques */ /* printf("Activate the consumer...\n"); */ while(cont) { - struct communication_assoc *cur; + int i; - discover_new_producers(); - cur = assoc_root.next; - while(cur != &assoc_root) + for (i = 0; i < nb_prod; i++) { - int i; + int nb_read; - for(i = 0; i < BUF_SIZE / sizeof(void *); i++) + for(nb_read = 0; nb_read < BUF_SIZE / sizeof(void *); nb_read++) { - void *tmp; - read(cur->pipefd[READ_IDX], &tmp, sizeof(void *)); - on_receive(tmp); + int j, n; + void *tmp_buf[BUF_SIZE / sizeof(void *)]; + + j = nb_read / sizeof(void *); + n = read(tcomms[i].pipefd[READ_IDX], (void *) ((uintptr_t) tmp_buf + nb_read), BUF_SIZE - nb_read); + if (n > 0) + { + nb_read += n; + for (; j + sizeof(void *) <= nb_read / sizeof(void *); j += sizeof(void *)) + on_receive(tmp_buf[j]); + } } - cur = cur->next; } } } diff --git a/communication_techniques/src/shared_mem.c b/communication_techniques/src/shared_mem.c index 9e16140..0487236 100644 --- a/communication_techniques/src/shared_mem.c +++ b/communication_techniques/src/shared_mem.c @@ -4,25 +4,21 @@ #include /* Non standard include */ -#include +#include +#include #include -__thread void **shared_space; +__thread volatile void **shared_space; __thread volatile int cons_idx = 0; __thread volatile int prod_idx = 0; -struct communication_assoc *create_comm_assoc(void) +void init_thread_comm(struct thread_comm *comm) { - struct communication_assoc *assoc; - - shared_space = (void **) malloc(SHARED_SPACE_SIZE); - assoc = (struct communication_assoc *) malloc(sizeof(struct communication_assoc)); - assoc->tid = pthread_self(); - assoc->shared_space = shared_space; - assoc->cons_idx = &cons_idx; - assoc->prod_idx = &prod_idx; - return assoc; + shared_space = (volatile void **) malloc(SHARED_SPACE_SIZE); + comm->shared_space = shared_space; + comm->cons_idx = &cons_idx; + comm->prod_idx = &prod_idx; } void reception(void (*on_receive)(void *)) @@ -31,21 +27,20 @@ void reception(void (*on_receive)(void *)) /* printf("Activate the consumer...\n"); */ while(cont) { - struct communication_assoc *cur; + int i; - discover_new_producers(); - cur = assoc_root.next; - while(cur != &assoc_root) + for (i = 0; i < nb_prod; i++) { int cons_idx; - for(cons_idx = *cur->cons_idx; cons_idx != *cur->prod_idx; cons_idx = (cons_idx + 1) % SHARED_SPACE_VOIDPTR, *cur->cons_idx = cons_idx) + for(cons_idx = *tcomms[i].cons_idx; cons_idx != *tcomms[i].prod_idx; cons_idx = (cons_idx + 1) % SHARED_SPACE_VOIDPTR, *tcomms[i].cons_idx = cons_idx) { - void *tmp; - tmp = cur->shared_space[cons_idx]; - on_receive(tmp); + /* + * The behaviour of this is not documented but we know + * the values inside buf won't change during this affectation + */ + on_receive((void *) tcomms[i].shared_space[cons_idx]); } - cur = cur->next; } } } diff --git a/communication_techniques/src/shared_mem_opt.c b/communication_techniques/src/shared_mem_opt.c index 4b26f34..127e556 100644 --- a/communication_techniques/src/shared_mem_opt.c +++ b/communication_techniques/src/shared_mem_opt.c @@ -4,25 +4,21 @@ #include /* Non standard include */ -#include +#include +#include #include -__thread void **shared_space; +__thread volatile void **shared_space; __thread volatile int cons_idx = 0; __thread volatile int prod_idx = 0; -struct communication_assoc *create_comm_assoc(void) +void init_thread_comm(struct thread_comm *comm) { - struct communication_assoc *assoc; - - shared_space = (void **) malloc(SHARED_SPACE_SIZE); - assoc = (struct communication_assoc *) malloc(sizeof(struct communication_assoc)); - assoc->tid = pthread_self(); - assoc->shared_space = shared_space; - assoc->cons_idx = &cons_idx; - assoc->prod_idx = &prod_idx; - return assoc; + shared_space = (volatile void **) malloc(SHARED_SPACE_SIZE); + comm->shared_space = shared_space; + comm->cons_idx = &cons_idx; + comm->prod_idx = &prod_idx; } void reception(void (*on_receive)(void *)) @@ -31,27 +27,26 @@ void reception(void (*on_receive)(void *)) /* printf("Activate the consumer...\n"); */ while(cont) { - struct communication_assoc *cur; + int i; - discover_new_producers(); - cur = assoc_root.next; - while(cur != &assoc_root) + for( i = 0; i < nb_prod; i++) { int cons_idx, prod_idx; - cons_idx = *cur->cons_idx; + cons_idx = *tcomms[i].cons_idx; do { - prod_idx = *cur->prod_idx; + prod_idx = *tcomms[i].prod_idx; for(; cons_idx != prod_idx; cons_idx = (cons_idx + 1) % SHARED_SPACE_VOIDPTR) { - void *tmp; - tmp = cur->shared_space[cons_idx]; - on_receive(tmp); + /* + * The behaviour of this is not documented but we know + * the values inside buf won't change during this affectation + */ + on_receive((void *) tcomms[i].shared_space[cons_idx]); } - } while (prod_idx != *cur->prod_idx); - *cur->cons_idx = cons_idx; - cur = cur->next; + } while (prod_idx != *tcomms[i].prod_idx); + *tcomms[i].cons_idx = cons_idx; } } } From 8f352457a05b8db062eae1c255178550886b8ebd Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Thu, 18 Jun 2009 18:31:15 +0200 Subject: [PATCH 06/62] Compile with changes of papihighlevel * commit 0ab6aa7576ac5ccdd9d0f99630016a2be87993b3 changed the API of print_result --- jikes_write_barrier/src/lip6/jikesrvm/bench/Main.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jikes_write_barrier/src/lip6/jikesrvm/bench/Main.java b/jikes_write_barrier/src/lip6/jikesrvm/bench/Main.java index 41b6dce..1f0d7e1 100644 --- a/jikes_write_barrier/src/lip6/jikesrvm/bench/Main.java +++ b/jikes_write_barrier/src/lip6/jikesrvm/bench/Main.java @@ -43,7 +43,8 @@ public class Main return; } bubbleSort(); - if (PapiHighLevel.print_results() != 0) + /* Only the 6 store in the if of the bubbleSort call the write barrier */ + if (PapiHighLevel.print_results(6, NB_ELEM) != 0) { System.err.println("Error while getting results"); java.lang.System.exit(2); From d8b88b0e7fc38e56358aa62e6fb953c5383ca1af Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Thu, 18 Jun 2009 18:33:12 +0200 Subject: [PATCH 07/62] commtech bench: BUGFIX of initialization * Initialization can be blocking --- communication_techniques/src/common.c | 1 + 1 file changed, 1 insertion(+) diff --git a/communication_techniques/src/common.c b/communication_techniques/src/common.c index 3566dd5..e7a7cca 100644 --- a/communication_techniques/src/common.c +++ b/communication_techniques/src/common.c @@ -51,6 +51,7 @@ void init_producer_thread(void) init_thread_comm(&tcomms[i_local]); pthread_mutex_lock(&init_lock); init = 1; + pthread_cond_signal(&init_cond); pthread_mutex_unlock(&init_lock); } From e3b01f93577bb72975bdd9aea7061a6ca70c9639 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Thu, 18 Jun 2009 18:39:42 +0200 Subject: [PATCH 08/62] commtechs bench: Reflect changes of papihighlevel * commit 0ab6aa7576ac5ccdd9d0f99630016a2be87993b3 changed the API of print_result --- communication_techniques/src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/communication_techniques/src/main.c b/communication_techniques/src/main.c index c26cd05..90b8a9c 100644 --- a/communication_techniques/src/main.c +++ b/communication_techniques/src/main.c @@ -187,7 +187,7 @@ void *producer(void *unused) for(j = 0; j < (BUF_SIZE / sizeof(uintptr_t)); j++) send(&k); } - print_results(); + print_results(BUF_SIZE / sizeof(uintptr_t), nb_cache_lines); } printf("[%p] Producer finished !\n", (void*) pthread_self()); /* From dc6cd83ac124d19a7e7a7025188eae709f6f57a5 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Thu, 18 Jun 2009 22:10:15 +0200 Subject: [PATCH 09/62] commtechs bench: BUGFIX in options parsing * nb_prod was tested with nb_cache_lines * buf_size is unused => removed * nb_cache_line => nb_bufs_sent --- communication_techniques/src/main.c | 47 ++++++++++++----------------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/communication_techniques/src/main.c b/communication_techniques/src/main.c index 90b8a9c..f11ee60 100644 --- a/communication_techniques/src/main.c +++ b/communication_techniques/src/main.c @@ -15,9 +15,13 @@ #include #include -static long nb_cache_lines = 0; + +#define toString(x) doStringification(x) +#define doStringification(x) #x + + +static long nb_bufs_sent = 0; long nb_prod = 0; -static long size_buf = 1; static char *calculation_lib = NULL; static int shared = 0; pthread_cond_t cond_cons_has_finished = PTHREAD_COND_INITIALIZER; @@ -29,7 +33,8 @@ void usage(char *argv[]) { char format[] = "-n [options]"; char options[] = "Required options :\n" - "-n nb_cache_lines\tNumber of cache lines to send to another core\n" + "-n nb_buffer_sent\tNumber of buffer to send to another core\n" + "\t\t\tBuffer size is " toString(BUF_SIZE) " bytes\n" "-p nb_producers\tNumber of producers which send data to another core\n" "Facultative options :\n" "-h\t\t\tPrint this help\n" @@ -46,26 +51,10 @@ int analyse_options(int argc, char *argv[]) int opt; opterr = 0; - while ((opt = getopt(argc, argv, ":hsc:n:p:b:")) != -1) + while ((opt = getopt(argc, argv, ":hsc:n:p:")) != -1) { switch (opt) { - case 'b' : - { - char *inval; - size_buf = strtol(optarg, &inval, 10); - if ((*optarg == '\0') || (*inval != '\0')) - { - fprintf(stderr, "Option '-b' needs an integer argument\n"); - return -1; - } - if ((nb_cache_lines <= 0) || ((nb_cache_lines == LONG_MAX) && errno == ERANGE)) - { - fprintf(stderr, "Number of cache lines for each buffer must be between 1 and %ld, both inclusive\n", LONG_MAX); - return -1; - } - } - break; case 'c' : calculation_lib = optarg; { @@ -83,13 +72,13 @@ int analyse_options(int argc, char *argv[]) case 'n' : { char *inval; - nb_cache_lines = strtol(optarg, &inval, 10); + nb_bufs_sent = strtol(optarg, &inval, 10); if ((*optarg == '\0') || (*inval != '\0')) { fprintf(stderr, "Option '-n' needs an integer argument\n"); return -1; } - if ((nb_cache_lines <= 0) || ((nb_cache_lines == LONG_MAX) && errno == ERANGE)) + if ((nb_bufs_sent <= 0) || ((nb_bufs_sent == LONG_MAX) && errno == ERANGE)) { fprintf(stderr, "Number of cache lines to be sent must be between 1 and %ld, both inclusive\n", LONG_MAX); return -1; @@ -105,7 +94,7 @@ int analyse_options(int argc, char *argv[]) fprintf(stderr, "Option '-p' needs an integer argument\n"); return -1; } - if ((nb_cache_lines <= 0) || ((nb_cache_lines == LONG_MAX) && errno == ERANGE)) + if ((nb_prod <= 0) || ((nb_prod == LONG_MAX) && errno == ERANGE)) { fprintf(stderr, "Number of producers must be between 1 and %ld, both inclusive\n", LONG_MAX); return -1; @@ -114,7 +103,7 @@ int analyse_options(int argc, char *argv[]) break; case 's' : shared = 1; - /* TODO: shared L2 cache */ + /* TODO: shared Ln cache */ break; case '?' : fprintf(stderr, "Option inconnue\n"); @@ -127,7 +116,7 @@ int analyse_options(int argc, char *argv[]) return -1; } } - if (!nb_cache_lines) + if (!nb_bufs_sent) { fprintf(stderr, "You must give the number of cache lines to be sent\n"); return -1; @@ -182,12 +171,16 @@ void *producer(void *unused) k = (void *) 0x6384923; if (initialize_papi() != -1) { - for(i = 0; i < nb_cache_lines; i++) { + for(i = 0; i < nb_bufs_sent; i++) { //printf("[%p] Send %d new CACHE_LINE\n", (void *) pthread_self(), BUF_SIZE / CACHE_LINE_SIZE); for(j = 0; j < (BUF_SIZE / sizeof(uintptr_t)); j++) + { send(&k); + if (unlikely(calculation_lib != NULL)) + usleep(1000); + } } - print_results(BUF_SIZE / sizeof(uintptr_t), nb_cache_lines); + print_results(BUF_SIZE / sizeof(uintptr_t), nb_bufs_sent); } printf("[%p] Producer finished !\n", (void*) pthread_self()); /* From 037895a73bdf618388e1711c887a630552b20343 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Thu, 18 Jun 2009 22:16:29 +0200 Subject: [PATCH 10/62] commtechs bench: Ready to bench * Add a script to launch all binaries * add a logclean target to Makefile * git ignore logs --- communication_techniques/.gitignore | 1 + communication_techniques/Makefile | 4 + communication_techniques/lancement.sh | 111 ++++++++++++++++++++++++++ 3 files changed, 116 insertions(+) create mode 100755 communication_techniques/lancement.sh diff --git a/communication_techniques/.gitignore b/communication_techniques/.gitignore index 8e16f6e..798d385 100644 --- a/communication_techniques/.gitignore +++ b/communication_techniques/.gitignore @@ -1 +1,2 @@ include/specific_comm.h +logs/* diff --git a/communication_techniques/Makefile b/communication_techniques/Makefile index 65c4781..ee50b7c 100644 --- a/communication_techniques/Makefile +++ b/communication_techniques/Makefile @@ -4,6 +4,7 @@ BINDIR=bin SRCDIR=src INCDIR=include LIBDIR=lib +LOGDIR=logs LOCALDIR=$(HOME)/local PAPIHIGHLEVELLIBDIR=lib PAPIHIGHLEVELINCDIR=include @@ -66,6 +67,9 @@ clean: rm -f $(INCDIR)/specific_comm.h rm -rf $(OBJDIR) +logclean: + rm -rf $(LOGDIR) + distclean: clean rm -rf $(BINDIR) $(LIBDIR) diff --git a/communication_techniques/lancement.sh b/communication_techniques/lancement.sh new file mode 100755 index 0000000..d6c5c06 --- /dev/null +++ b/communication_techniques/lancement.sh @@ -0,0 +1,111 @@ +#! /bin/bash + +set -u + +# Files and directories +binDir="bin" +thisScript="$0" + +# Param +binList="asm_cache_comm c_cache_comm pipe_comm shared_mem_comm shared_mem_opt_comm jikes_barrier_comm" # Type de communication +nbProdList="1" # Nombre de cores producteurs +typeProdList="none matrice" # Methode pour produire les valeurs +typeCacheList="L2 mem" # Niveau de cache partage + +# Const +nbIter="5000000" # Nb de lignes produites +sizeBuf="1" # En nombre de lignes de cache + +# Nom generique des fichiers de log +logFileName="\$perfDirName/cache_\$typeCache-nbProd_\$nbProd-typeProd_\$typeProd-nbIter_\$nbIter-\$bin" +expDirName="logs" +perfDirName="$expDirName/perfCommMulti-`date +'%F-%Hh%Mm%S'`" + +if [ -n $LD_LIBRARY_PATH ] +then + LD_LIBRARY_PATH_LEFT="${LD_LIBRARY_PATH}" + while [ -n "${LD_LIBRARY_PATH_LEFT}" ] + do + aLibDir="${LD_LIBRARY_PATH_LEFT%%:*}" + if [ -x ${aLibDir}/libpapi.so ] + then + papiLibPresent="1"; + fi + if [ -x ${aLibDir}/libpapihighlevel.so ] + then + papiHighLevelLibPresent="1"; + fi + if [ -n "${papiLibPresent}" -a -n "${papiHighLevelLibPresent}" ] + then + break + fi + LD_LIBRARY_PATH_LEFT="${LD_LIBRARY_PATH#*:}" + done + if [ -z "${papiLibPresent}" -o -z "${papiHighLevelLibPresent}" ] + then + echo "Libraries needed for this bench not accessible by \$LD_LIBRARY_PATH" > /dev/stderr # Is there a better way to display something on stderr ? + exit 1 + fi +else + echo "Libraries needed for this bench not accessible by \$LD_LIBRARY_PATH" > /dev/stderr # Is there a better way to display something on stderr ? + exit 1 +fi +unset papiLibPresent +unset papiHighLevelLibPresent +unset LD_LIBRARY_PATH_LEFT + +[ -d "$expDirName" ] || mkdir "$expDirName" +[ -d "$perfDirName" ] || mkdir "$perfDirName" + +function_run () { + case $typeProd in + "none" ) optTypeProd="" ;; + "matrice" ) optTypeProd="-c $thisScript" ;; + * ) exit 1 ;; + esac + case $typeCache in + "mem" ) optTypeCache="-s 0" ;; + "L2" ) optTypeCache="-s 2" ;; + * ) exit 1 ;; + esac + + make $binDir/$bin + echo "On lance : \"${bin##*/} $optTypeCache $optTypeProd -p $nbProd -n $nbIter\"" + beginingDate=`date +%s` + + ( $binDir/$bin $optTypeCache $optTypeProd -p $nbProd -n $nbIter || echo "echec experience" ) | eval tee $logFileName + endDate=`date +%s` + duration_sec=`expr \( $endDate - $beginingDate \) % 60` + duration_min=`expr \( $endDate - $beginingDate \) / 60` + duration_hrs=`expr $duration_min / 60` + duration_min=`expr $duration_min % 60` + + echo "Fin de l'experience : `date +'%H:%M:%S (%d/%m/%y)'`" + echo "La duree est de : ${duration_hrs}hrs ${duration_min}min ${duration_sec}sec" + echo "" +} + + + +echo -e "On commence les perfs\n" +globalBeginingDate=`date +%s` + +for nbProd in $nbProdList ; do + for typeProd in $typeProdList; do + for typeCache in $typeCacheList ; do + for bin in $binList ; do + function_run + done + done + done +done + +globalEndDate=`date +%s` +globalDuration_sec=`expr \( $globalEndDate - $globalBeginingDate \) % 60` +globalDuration_min=`expr \( $globalEndDate - $globalBeginingDate \) / 60` +globalDuration_hrs=`expr $globalDuration_min / 60` +globalDuration_min=`expr $globalDuration_min % 60` + +echo "Fin de la serie d'experience : `date +'%H:%M:%S (%d/%m/%y)'`" +echo "La duree totale est de : ${globalDuration_hrs}hrs ${globalDuration_min}min ${globalDuration_sec}sec" + From f9128c0348331b32ce716f3ce6776b7db68477e5 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Fri, 19 Jun 2009 13:27:08 +0200 Subject: [PATCH 11/62] commtechs bench: Addresses are calculated --- communication_techniques/Makefile | 2 +- communication_techniques/src/main.c | 55 ++++++++++++++++++++++------- 2 files changed, 44 insertions(+), 13 deletions(-) diff --git a/communication_techniques/Makefile b/communication_techniques/Makefile index ee50b7c..97fa3fe 100644 --- a/communication_techniques/Makefile +++ b/communication_techniques/Makefile @@ -13,7 +13,7 @@ PAPIHIGHLEVELINCDIR=include # I know -finline-functions and -finline-functions-called-once are enabled by # -O3 but I did this in case gcc behaviour change one day CFLAGS=-g -O3 -finline-functions -finline-functions-called-once -Wall -Werror -LDFLAGS=-L$(LIBDIR) -L$(LOCALDIR)/$(PAPIHIGHLEVELLIBDIR) -Wl,-rpath-link,$(HOME)/local/lib -lpthread -lpapihighlevel +LDFLAGS=-L$(LIBDIR) -L$(LOCALDIR)/$(PAPIHIGHLEVELLIBDIR) -Wl,-rpath-link,$(HOME)/local/lib -lpthread -lpapihighlevel -ldl # Executables CC=gcc diff --git a/communication_techniques/src/main.c b/communication_techniques/src/main.c index f11ee60..4e24fd2 100644 --- a/communication_techniques/src/main.c +++ b/communication_techniques/src/main.c @@ -9,6 +9,7 @@ #include #include #include +#include /* Non standards includes */ #include @@ -22,7 +23,9 @@ static long nb_bufs_sent = 0; long nb_prod = 0; -static char *calculation_lib = NULL; +static void (*init_calc)(void) = NULL; +static void *(*do_calc)(void) = NULL; +static void (*end_calc)(void) = NULL; static int shared = 0; pthread_cond_t cond_cons_has_finished = PTHREAD_COND_INITIALIZER; pthread_mutex_t mutex_cons_has_finished = PTHREAD_MUTEX_INITIALIZER; @@ -39,13 +42,24 @@ void usage(char *argv[]) "Facultative options :\n" "-h\t\t\tPrint this help\n" "-s\t\t\tShare the same L2 cache or not\n" - "-c calculation_lib\tLibrary to use for calculation\n" + "-c calculation_libname\tLibrary to use for calculation\n" "\t\t\tThis library must implement functions in calc.h\n"; printf("Usage : %s %s\n", argv[0], format); printf("Options :\n"); printf("%s\n", options); } +void do_nothing(void) +{ +} + +void *do_nocalc(void) +{ + static int an_int; + + return &an_int; +} + int analyse_options(int argc, char *argv[]) { int opt; @@ -56,12 +70,27 @@ int analyse_options(int argc, char *argv[]) switch (opt) { case 'c' : - calculation_lib = optarg; { struct stat file_stat; - if (stat(calculation_lib, &file_stat)) + void *dl_descriptor; + + if (stat(optarg, &file_stat)) { - printf("%s: %s\n", optarg, strerror(errno)); + fprintf(stderr, "%s: %s\n", optarg, strerror(errno)); + return -1; + } + dl_descriptor = dlopen(optarg, RTLD_LAZY | RTLD_LOCAL); + if (dl_descriptor == NULL) + { + fprintf(stderr, "dlopen error: %s\n", dlerror()); + return -1; + } + init_calc = dlsym(dl_descriptor, "init_calc"); + do_calc = dlsym(dl_descriptor, "do_calc"); + end_calc = dlsym(dl_descriptor, "end_calc"); + if ((init_calc == NULL) || (do_calc == NULL) || (end_calc == NULL)) + { + fprintf(stderr, "A symbol cannot be loaded: %s\n", dlerror()); return -1; } } @@ -131,13 +160,18 @@ int analyse_options(int argc, char *argv[]) fprintf(stderr, "Too many producers to fit with the consumer in processors which share a same cache\n"); return -1; } + if (do_calc == NULL) + { + init_calc = do_nothing; + do_calc = do_nocalc; + end_calc = do_nothing; + } return 0; } void *producer(void *unused) { int i, j; - void *k; init_producer_thread(); if (shared) @@ -168,20 +202,17 @@ void *producer(void *unused) return NULL; } } - k = (void *) 0x6384923; + init_calc(); if (initialize_papi() != -1) { for(i = 0; i < nb_bufs_sent; i++) { //printf("[%p] Send %d new CACHE_LINE\n", (void *) pthread_self(), BUF_SIZE / CACHE_LINE_SIZE); for(j = 0; j < (BUF_SIZE / sizeof(uintptr_t)); j++) - { - send(&k); - if (unlikely(calculation_lib != NULL)) - usleep(1000); - } + send(do_calc()); } print_results(BUF_SIZE / sizeof(uintptr_t), nb_bufs_sent); } + end_calc(); printf("[%p] Producer finished !\n", (void*) pthread_self()); /* * When a producer end its thread-local storage vanished. Thus, From f4b39045411c1f626446ab6d98fb8ef2979987e5 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Fri, 19 Jun 2009 20:53:34 +0200 Subject: [PATCH 12/62] commtechs bench: add calc_mat calculation lib * Add a matrice calculation as one of the possible calculation * Modify the makefile to permit calculation lib compilation * Reorganize the makefile to be able to execute the default target --- communication_techniques/Makefile | 80 +++++++++++-------- .../src/calculation/calc_mat.c | 40 ++++++++++ 2 files changed, 88 insertions(+), 32 deletions(-) create mode 100644 communication_techniques/src/calculation/calc_mat.c diff --git a/communication_techniques/Makefile b/communication_techniques/Makefile index 97fa3fe..bc2d5fd 100644 --- a/communication_techniques/Makefile +++ b/communication_techniques/Makefile @@ -1,61 +1,67 @@ # Directories -OBJDIR=obj -BINDIR=bin -SRCDIR=src -INCDIR=include -LIBDIR=lib -LOGDIR=logs -LOCALDIR=$(HOME)/local -PAPIHIGHLEVELLIBDIR=lib -PAPIHIGHLEVELINCDIR=include +OBJDIR:=obj +BINDIR:=bin +SRCDIR:=src +INCDIR:=include +LIBDIR:=lib +LOGDIR:=logs +LOCALDIR:=$(HOME)/local +PAPIHIGHLEVELLIBDIR:=lib +PAPIHIGHLEVELINCDIR:=include +CALCDIR:=calculation # Compilation flags # I know -finline-functions and -finline-functions-called-once are enabled by # -O3 but I did this in case gcc behaviour change one day -CFLAGS=-g -O3 -finline-functions -finline-functions-called-once -Wall -Werror -LDFLAGS=-L$(LIBDIR) -L$(LOCALDIR)/$(PAPIHIGHLEVELLIBDIR) -Wl,-rpath-link,$(HOME)/local/lib -lpthread -lpapihighlevel -ldl +CFLAGS:=-g -O3 -finline-functions -finline-functions-called-once -Wall -Werror +LDFLAGS:=-L$(LIBDIR) -L$(LOCALDIR)/$(PAPIHIGHLEVELLIBDIR) -Wl,-rpath-link,$(HOME)/local/lib -lpthread -lpapihighlevel -ldl # Executables CC=gcc # Files -BINNAMES=asm_cache_comm c_cache_comm pipe_comm shared_mem_comm shared_mem_opt_comm jikes_barrier_comm fake_comm -BINS=$(patsubst %, $(BINDIR)/%, $(BINNAMES)) -MAIN_OBJS=main.o common.o -COMMON_LIB_OBJS=common.o +BINNAMES:=asm_cache_comm c_cache_comm pipe_comm shared_mem_comm shared_mem_opt_comm jikes_barrier_comm fake_comm +CALCLIBSNAMES:=calc_mat +BINS:=$(patsubst %,$(BINDIR)/%,$(BINNAMES)) +CALCLIBS:=$(patsubst %,$(LIBDIR)/lib%.so.1,$(CALCLIBSNAMES)) +MAIN_OBJS:=main.o common.o +COMMON_LIB_OBJS:=common.o -.PHONY: all tidy clean distclean symlink +.PHONY: all tidy clean distclean .SECONDARY: .SUFFIXES: .c .o -default: $(BINS) - -ifneq (,$(findstring $(MAKECMDGOALS),$(BINS))) -BASE_TARGET=$(patsubst $(BINDIR)/%_comm,%,$(MAKECMDGOALS)) +default: $(BINS) $(CALCLIBS) # Compilation of binary -$(BINDIR)/$(BASE_TARGET)_comm: $(patsubst %,$(OBJDIR)/$(BASE_TARGET)_%,$(MAIN_OBJS)) $(LIBDIR)/lib$(BASE_TARGET).a +$(BINDIR)/%_comm: $(patsubst %,$(OBJDIR)/\%/%,$(MAIN_OBJS)) $(LIBDIR)/lib%.a if [ ! -d $(BINDIR) ] ; then mkdir $(BINDIR) ; fi $(CC) -o $@ $^ $(LDFLAGS) -# Compilation of library -$(LIBDIR)/lib$(BASE_TARGET).a: $(OBJDIR)/$(BASE_TARGET).o $(patsubst %,$(OBJDIR)/$(BASE_TARGET)_%,$(COMMON_LIB_OBJS)) +# Creation of comm library +$(LIBDIR)/lib%.a: $(OBJDIR)/%.o $(patsubst %,$(OBJDIR)/\%/%,$(COMMON_LIB_OBJS)) if [ ! -d $(LIBDIR) ] ; then mkdir $(LIBDIR) ; fi $(AR) -rcus $@ $^ -# Compile common source files -$(OBJDIR)/$(BASE_TARGET)_%.o: $(SRCDIR)/%.c symlink - if [ ! -d $(OBJDIR) ] ; then mkdir $(OBJDIR) ; fi - $(CC) $(CFLAGS) -I$(INCDIR) -I$(LOCALDIR)/$(PAPIHIGHLEVELINCDIR) -c $< -o $@ -endif +# Creation of calc library +$(LIBDIR)/libcalc_%.so.1: $(OBJDIR)/$(CALCDIR)/calc_%.o + if [ ! -d $(LIBDIR) ] ; then mkdir $(LIBDIR) ; fi + $(CC) $(LDFLAGS) -shared -Wl,-soname,libcalc_$*.so.1 -o $@ $< -# Compile non common source files -$(OBJDIR)/%.o: $(SRCDIR)/%.c symlink +# Compile lib specific source files +$(OBJDIR)/%.o: $(SRCDIR)/%.c $(INCDIR)/%_comm.h $(INCDIR)/commtech.h if [ ! -d $(OBJDIR) ] ; then mkdir $(OBJDIR) ; fi + cd $(INCDIR) ; ln -sfT $*_comm.h specific_comm.h $(CC) $(CFLAGS) -I$(INCDIR) -c $< -o $@ -symlink: - ln -sfT $(BASE_TARGET)_comm.h $(INCDIR)/specific_comm.h +# Rule for compiling common source files using libcomm is at the end of +# this file, after the .SECONDEXPANSION target + +# Compile source files not using libcomm +$(OBJDIR)/$(CALCDIR)/%.o: $(SRCDIR)/$(CALCDIR)/%.c + if [ ! -d $(OBJDIR) ] ; then mkdir $(OBJDIR) ; fi + if [ ! -d $(OBJDIR)/$(CALCDIR) ] ; then mkdir $(OBJDIR)/$(CALCDIR) ; fi + $(CC) $(CFLAGS) -I$(INCDIR) -c $< -o $@ #.%.d: %.c # gcc $(CFLAGS) -MM $^ | sed -e 's/\([^:]*\):\(.*\)/\1 $@: \2 Makefile/' > $@ @@ -82,3 +88,13 @@ distclean: clean #endif #endif #endif + +.SECONDEXPANSION: + +# Compile common source files using libcomm +$(OBJDIR)/%.o: $(SRCDIR)/$$(*F).c $(INCDIR)/$$(*D)_comm.h $(INCDIR)/commtech.h + if [ ! -d $(OBJDIR) ] ; then mkdir $(OBJDIR) ; fi + if [ ! -d $(OBJDIR)/$(*D) ] ; then mkdir $(OBJDIR)/$(*D) ; fi + cd $(INCDIR) ; ln -sfT $(*D)_comm.h specific_comm.h + $(CC) $(CFLAGS) -I$(INCDIR) -I$(LOCALDIR)/$(PAPIHIGHLEVELINCDIR) -c $< -o $@ + diff --git a/communication_techniques/src/calculation/calc_mat.c b/communication_techniques/src/calculation/calc_mat.c new file mode 100644 index 0000000..b551ade --- /dev/null +++ b/communication_techniques/src/calculation/calc_mat.c @@ -0,0 +1,40 @@ +#include + + +#define likely(x) __builtin_expect(!!(x), 1) +#define unlikely(x) __builtin_expect(!!(x), 0) + + +static int *mat, *vect; +static int li; +static int n = 16, m = 16; /* Size of the matrice: n lines, m columns */ + +void init_calc(void) +{ + int i; + + srand(42); + mat = (int *) malloc(n * m * sizeof(int)); + vect = (int *) malloc(m * sizeof(int)); + for (i = 0; i < n * m; i++) + mat[i] = rand(); + li = 0; +} + +void *do_calc(void) +{ + int co, p = 0; + + for (co = 0; co < m; co++) + p += mat[li * m + co] * vect[li]; + mat[li * m] = p; + if (unlikely(++li >= n)) + li = 0; + return &mat[li * m]; +} + +void end_calc(void) +{ + free(mat); + free(vect); +} From a590ecca090266949a43274c55e075e3bed0b8a5 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Fri, 19 Jun 2009 21:15:23 +0200 Subject: [PATCH 13/62] commtechs bench: calculation init takes an arg --- .../src/calculation/calc_mat.c | 6 ++++-- communication_techniques/src/main.c | 15 ++++++++++----- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/communication_techniques/src/calculation/calc_mat.c b/communication_techniques/src/calculation/calc_mat.c index b551ade..149c7e5 100644 --- a/communication_techniques/src/calculation/calc_mat.c +++ b/communication_techniques/src/calculation/calc_mat.c @@ -7,12 +7,14 @@ static int *mat, *vect; static int li; -static int n = 16, m = 16; /* Size of the matrice: n lines, m columns */ +static int n, m; /* Size of the matrice: n lines, m columns */ -void init_calc(void) +void init_calc(int size) { int i; + n = size; + m = size; srand(42); mat = (int *) malloc(n * m * sizeof(int)); vect = (int *) malloc(m * sizeof(int)); diff --git a/communication_techniques/src/main.c b/communication_techniques/src/main.c index 4e24fd2..614b112 100644 --- a/communication_techniques/src/main.c +++ b/communication_techniques/src/main.c @@ -19,11 +19,12 @@ #define toString(x) doStringification(x) #define doStringification(x) #x +#define INIT_CALC_ARG 16 static long nb_bufs_sent = 0; long nb_prod = 0; -static void (*init_calc)(void) = NULL; +static void (*init_calc)(int) = NULL; static void *(*do_calc)(void) = NULL; static void (*end_calc)(void) = NULL; static int shared = 0; @@ -49,7 +50,7 @@ void usage(char *argv[]) printf("%s\n", options); } -void do_nothing(void) +void do_noinit(int unused) { } @@ -60,6 +61,10 @@ void *do_nocalc(void) return &an_int; } +void do_noend(void) +{ +} + int analyse_options(int argc, char *argv[]) { int opt; @@ -162,9 +167,9 @@ int analyse_options(int argc, char *argv[]) } if (do_calc == NULL) { - init_calc = do_nothing; + init_calc = do_noinit; do_calc = do_nocalc; - end_calc = do_nothing; + end_calc = do_noend; } return 0; } @@ -202,7 +207,7 @@ void *producer(void *unused) return NULL; } } - init_calc(); + init_calc(INIT_CALC_ARG); if (initialize_papi() != -1) { for(i = 0; i < nb_bufs_sent; i++) { From 7b36e81b4084897ba8e9aa70a66b59a0871ae3b1 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Tue, 23 Jun 2009 11:56:22 +0200 Subject: [PATCH 14/62] commtech: Currently no L2 shared needs no -s --- communication_techniques/lancement.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/communication_techniques/lancement.sh b/communication_techniques/lancement.sh index d6c5c06..5d86e2c 100755 --- a/communication_techniques/lancement.sh +++ b/communication_techniques/lancement.sh @@ -64,7 +64,7 @@ function_run () { * ) exit 1 ;; esac case $typeCache in - "mem" ) optTypeCache="-s 0" ;; + "mem" ) optTypeCache="" ;; "L2" ) optTypeCache="-s 2" ;; * ) exit 1 ;; esac From cc1bde60c978541f6e8bdef429b6869ac7756174 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Tue, 23 Jun 2009 11:57:25 +0200 Subject: [PATCH 15/62] commtech: Add fake_comm in lancement.sh script --- communication_techniques/lancement.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/communication_techniques/lancement.sh b/communication_techniques/lancement.sh index 5d86e2c..3dc7083 100755 --- a/communication_techniques/lancement.sh +++ b/communication_techniques/lancement.sh @@ -7,7 +7,7 @@ binDir="bin" thisScript="$0" # Param -binList="asm_cache_comm c_cache_comm pipe_comm shared_mem_comm shared_mem_opt_comm jikes_barrier_comm" # Type de communication +binList="asm_cache_comm c_cache_comm pipe_comm shared_mem_comm shared_mem_opt_comm jikes_barrier_comm fake_comm" # Type de communication nbProdList="1" # Nombre de cores producteurs typeProdList="none matrice" # Methode pour produire les valeurs typeCacheList="L2 mem" # Niveau de cache partage From e39c05664a92a2b32ff55aa6856ca31723db47f1 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Tue, 23 Jun 2009 12:25:36 +0200 Subject: [PATCH 16/62] comm lib have their own directory as calc libs --- communication_techniques/Makefile | 25 +++++++++++++------ communication_techniques/lancement.sh | 4 +-- .../src/{ => communication}/asm_cache.c | 0 .../src/{ => communication}/c_cache.c | 0 .../src/{ => communication}/common.c | 0 .../src/{ => communication}/fake.c | 0 .../src/{ => communication}/jikes_barrier.c | 0 .../src/{ => communication}/pipe.c | 0 .../src/{ => communication}/shared_mem.c | 0 .../src/{ => communication}/shared_mem_opt.c | 0 10 files changed, 20 insertions(+), 9 deletions(-) rename communication_techniques/src/{ => communication}/asm_cache.c (100%) rename communication_techniques/src/{ => communication}/c_cache.c (100%) rename communication_techniques/src/{ => communication}/common.c (100%) rename communication_techniques/src/{ => communication}/fake.c (100%) rename communication_techniques/src/{ => communication}/jikes_barrier.c (100%) rename communication_techniques/src/{ => communication}/pipe.c (100%) rename communication_techniques/src/{ => communication}/shared_mem.c (100%) rename communication_techniques/src/{ => communication}/shared_mem_opt.c (100%) diff --git a/communication_techniques/Makefile b/communication_techniques/Makefile index bc2d5fd..0c724ba 100644 --- a/communication_techniques/Makefile +++ b/communication_techniques/Makefile @@ -9,6 +9,7 @@ LOCALDIR:=$(HOME)/local PAPIHIGHLEVELLIBDIR:=lib PAPIHIGHLEVELINCDIR:=include CALCDIR:=calculation +COMMDIR:=communication # Compilation flags # I know -finline-functions and -finline-functions-called-once are enabled by @@ -23,8 +24,8 @@ CC=gcc BINNAMES:=asm_cache_comm c_cache_comm pipe_comm shared_mem_comm shared_mem_opt_comm jikes_barrier_comm fake_comm CALCLIBSNAMES:=calc_mat BINS:=$(patsubst %,$(BINDIR)/%,$(BINNAMES)) -CALCLIBS:=$(patsubst %,$(LIBDIR)/lib%.so.1,$(CALCLIBSNAMES)) -MAIN_OBJS:=main.o common.o +CALCLIBS:=$(patsubst %,$(LIBDIR)/$(CALCDIR)/lib%.so.1,$(CALCLIBSNAMES)) +MAIN_OBJS:=main.o COMMON_LIB_OBJS:=common.o .PHONY: all tidy clean distclean @@ -34,23 +35,27 @@ COMMON_LIB_OBJS:=common.o default: $(BINS) $(CALCLIBS) # Compilation of binary -$(BINDIR)/%_comm: $(patsubst %,$(OBJDIR)/\%/%,$(MAIN_OBJS)) $(LIBDIR)/lib%.a +$(BINDIR)/%_comm: $(patsubst %,$(OBJDIR)/\%/%,$(MAIN_OBJS)) $(LIBDIR)/$(COMMDIR)/lib%.a if [ ! -d $(BINDIR) ] ; then mkdir $(BINDIR) ; fi $(CC) -o $@ $^ $(LDFLAGS) # Creation of comm library -$(LIBDIR)/lib%.a: $(OBJDIR)/%.o $(patsubst %,$(OBJDIR)/\%/%,$(COMMON_LIB_OBJS)) +$(LIBDIR)/$(COMMDIR)/lib%.a: $(OBJDIR)/$(COMMDIR)/%.o $(patsubst %,$(OBJDIR)/$(COMMDIR)/\%/%,$(COMMON_LIB_OBJS)) if [ ! -d $(LIBDIR) ] ; then mkdir $(LIBDIR) ; fi + if [ ! -d $(LIBDIR)/$(COMMDIR) ] ; then mkdir $(LIBDIR)/$(COMMDIR) ; fi $(AR) -rcus $@ $^ # Creation of calc library -$(LIBDIR)/libcalc_%.so.1: $(OBJDIR)/$(CALCDIR)/calc_%.o +$(LIBDIR)/$(CALCDIR)/libcalc_%.so.1: $(OBJDIR)/$(CALCDIR)/calc_%.o if [ ! -d $(LIBDIR) ] ; then mkdir $(LIBDIR) ; fi + if [ ! -d $(LIBDIR)/$(CALCDIR) ] ; then mkdir $(LIBDIR)/$(CALCDIR) ; fi $(CC) $(LDFLAGS) -shared -Wl,-soname,libcalc_$*.so.1 -o $@ $< + cd $(@D) ; ln -sf libcalc_$*.so.1 libcalc_$*.so # Compile lib specific source files -$(OBJDIR)/%.o: $(SRCDIR)/%.c $(INCDIR)/%_comm.h $(INCDIR)/commtech.h +$(OBJDIR)/$(COMMDIR)/%.o: $(SRCDIR)/$(COMMDIR)/%.c $(INCDIR)/%_comm.h $(INCDIR)/commtech.h if [ ! -d $(OBJDIR) ] ; then mkdir $(OBJDIR) ; fi + if [ ! -d $(OBJDIR)/$(COMMDIR) ] ; then mkdir $(OBJDIR)/$(COMMDIR) ; fi cd $(INCDIR) ; ln -sfT $*_comm.h specific_comm.h $(CC) $(CFLAGS) -I$(INCDIR) -c $< -o $@ @@ -92,9 +97,15 @@ distclean: clean .SECONDEXPANSION: # Compile common source files using libcomm +$(OBJDIR)/$(COMMDIR)/%.o: $(SRCDIR)/$(COMMDIR)/$$(*F).c $(INCDIR)/$$(*D)_comm.h $(INCDIR)/commtech.h + if [ ! -d $(OBJDIR) ] ; then mkdir $(OBJDIR) ; fi + if [ ! -d $(OBJDIR)/$(COMMDIR) ] ; then mkdir $(OBJDIR)/$(COMMDIR) ; fi + if [ ! -d $(OBJDIR)/$(COMMDIR)/$(*D) ] ; then mkdir $(OBJDIR)/$(COMMDIR)/$(*D) ; fi + cd $(INCDIR) ; ln -sfT $(*D)_comm.h specific_comm.h + $(CC) $(CFLAGS) -I$(INCDIR) -I$(LOCALDIR)/$(PAPIHIGHLEVELINCDIR) -c $< -o $@ + $(OBJDIR)/%.o: $(SRCDIR)/$$(*F).c $(INCDIR)/$$(*D)_comm.h $(INCDIR)/commtech.h if [ ! -d $(OBJDIR) ] ; then mkdir $(OBJDIR) ; fi if [ ! -d $(OBJDIR)/$(*D) ] ; then mkdir $(OBJDIR)/$(*D) ; fi cd $(INCDIR) ; ln -sfT $(*D)_comm.h specific_comm.h $(CC) $(CFLAGS) -I$(INCDIR) -I$(LOCALDIR)/$(PAPIHIGHLEVELINCDIR) -c $< -o $@ - diff --git a/communication_techniques/lancement.sh b/communication_techniques/lancement.sh index 3dc7083..035ea95 100755 --- a/communication_techniques/lancement.sh +++ b/communication_techniques/lancement.sh @@ -4,7 +4,7 @@ set -u # Files and directories binDir="bin" -thisScript="$0" +calcDir="calculation" # Param binList="asm_cache_comm c_cache_comm pipe_comm shared_mem_comm shared_mem_opt_comm jikes_barrier_comm fake_comm" # Type de communication @@ -60,7 +60,7 @@ unset LD_LIBRARY_PATH_LEFT function_run () { case $typeProd in "none" ) optTypeProd="" ;; - "matrice" ) optTypeProd="-c $thisScript" ;; + "matrice" ) optTypeProd="-c lib/${calcDir}/libcalc_mat.so" ;; * ) exit 1 ;; esac case $typeCache in diff --git a/communication_techniques/src/asm_cache.c b/communication_techniques/src/communication/asm_cache.c similarity index 100% rename from communication_techniques/src/asm_cache.c rename to communication_techniques/src/communication/asm_cache.c diff --git a/communication_techniques/src/c_cache.c b/communication_techniques/src/communication/c_cache.c similarity index 100% rename from communication_techniques/src/c_cache.c rename to communication_techniques/src/communication/c_cache.c diff --git a/communication_techniques/src/common.c b/communication_techniques/src/communication/common.c similarity index 100% rename from communication_techniques/src/common.c rename to communication_techniques/src/communication/common.c diff --git a/communication_techniques/src/fake.c b/communication_techniques/src/communication/fake.c similarity index 100% rename from communication_techniques/src/fake.c rename to communication_techniques/src/communication/fake.c diff --git a/communication_techniques/src/jikes_barrier.c b/communication_techniques/src/communication/jikes_barrier.c similarity index 100% rename from communication_techniques/src/jikes_barrier.c rename to communication_techniques/src/communication/jikes_barrier.c diff --git a/communication_techniques/src/pipe.c b/communication_techniques/src/communication/pipe.c similarity index 100% rename from communication_techniques/src/pipe.c rename to communication_techniques/src/communication/pipe.c diff --git a/communication_techniques/src/shared_mem.c b/communication_techniques/src/communication/shared_mem.c similarity index 100% rename from communication_techniques/src/shared_mem.c rename to communication_techniques/src/communication/shared_mem.c diff --git a/communication_techniques/src/shared_mem_opt.c b/communication_techniques/src/communication/shared_mem_opt.c similarity index 100% rename from communication_techniques/src/shared_mem_opt.c rename to communication_techniques/src/communication/shared_mem_opt.c From f8c2be94787083c729fb1a0d77e18760c83fa800 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Tue, 23 Jun 2009 12:31:48 +0200 Subject: [PATCH 17/62] commtech: -s don't take an argument --- communication_techniques/lancement.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/communication_techniques/lancement.sh b/communication_techniques/lancement.sh index 035ea95..93ebf28 100755 --- a/communication_techniques/lancement.sh +++ b/communication_techniques/lancement.sh @@ -65,7 +65,7 @@ function_run () { esac case $typeCache in "mem" ) optTypeCache="" ;; - "L2" ) optTypeCache="-s 2" ;; + "L2" ) optTypeCache="-s" ;; * ) exit 1 ;; esac From 857a764485cc50a5ffaca935f556312c6f608d49 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Tue, 23 Jun 2009 12:45:15 +0200 Subject: [PATCH 18/62] commtechs bench: Add parsing of logs --- communication_techniques/lancement.sh | 2 +- communication_techniques/parsing.sh | 52 +++++++++++++++++++++++++++ papihighlevel | 2 +- 3 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 communication_techniques/parsing.sh diff --git a/communication_techniques/lancement.sh b/communication_techniques/lancement.sh index 93ebf28..3263a8a 100755 --- a/communication_techniques/lancement.sh +++ b/communication_techniques/lancement.sh @@ -17,7 +17,7 @@ nbIter="5000000" # Nb de lignes produites sizeBuf="1" # En nombre de lignes de cache # Nom generique des fichiers de log -logFileName="\$perfDirName/cache_\$typeCache-nbProd_\$nbProd-typeProd_\$typeProd-nbIter_\$nbIter-\$bin" +logFileName="\$perfDirName/cache_\$typeCache-nbProd_\$nbProd-typeProd_\$typeProd-nbIter_\$nbIter-\$bin.log" expDirName="logs" perfDirName="$expDirName/perfCommMulti-`date +'%F-%Hh%Mm%S'`" diff --git a/communication_techniques/parsing.sh b/communication_techniques/parsing.sh new file mode 100644 index 0000000..b20030f --- /dev/null +++ b/communication_techniques/parsing.sh @@ -0,0 +1,52 @@ +#! /bin/bash + +set -u + +#comList = `ls | perl -pi -e 's/.*-(\w+)_com/$1/' | sort | uniq` +comList=`ls *.log | perl -ni -e '/-([^-]+)_comm/; $a{$1}=""; END { foreach ( sort keys %a ) {print "$_ "}}'` +cacheList=`ls *log | perl -ni -e '/cache_([^-]+)-/; $a{$1}=""; END { foreach ( sort keys %a ) {print "$_ "}}'` +prodList=`ls *.log | perl -ni -e '/typeProd_([^-]+)-/; $a{$1}=""; END { foreach ( sort keys %a ) {print "$_ "}}'` + +metriqueList="cache_hits cache_miss cycles" + +echo "set style data histogram" > multicores.gnuplot +echo "set style histogram cluster gap 1" >> multicores.gnuplot +echo "set style fill solid border -1" >> multicores.gnuplot +echo "set boxwidth 0.9" >> multicores.gnuplot +echo "set xtic rotate by -45" >> multicores.gnuplot +echo "set bmargin 5" >> multicores.gnuplot +echo "set terminal postscript landscape color" >> multicores.gnuplot + +for prod in $prodList ; do + for metrique in $metriqueList ; do + > prod_$prod-$metrique.dat + done + for com in $comList ; do + for metrique in $metriqueList ; do + echo -ne "\n$com\t\t" >> prod_$prod-$metrique.dat + done + for cache in $cacheList ; do + for metrique in $metriqueList ; do + for value in `perl -n -e "print '$1 $2 $3' if /${metrique}.* (\\d+) \\/ (\\d+) \\/ (\\d+)/" cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do + echo -ne "\t$value " >> prod_$prod-${metrique}.dat + done + done + done + done + for metrique in $metriqueList ; do + echo "set output 'prod_$prod-$metrique-total.ps'" >> multicores.gnuplot + echo "plot 'prod_$prod-$metrique.dat' using 2:xtic(1) ti 'L2', '' u 5 ti 'MEM'" >> multicores.gnuplot + echo "set output 'prod_$prod-$metrique-byLoop.ps'" >> multicores.gnuplot + echo "plot 'prod_$prod-$metrique.dat' using 3:xtic(1) ti 'L2', '' u 6 ti 'MEM'" >> multicores.gnuplot + echo "set output 'prod_$prod-$metrique-byWrite.ps'" >> multicores.gnuplot + echo "plot 'prod_$prod-$metrique.dat' using 4:xtic(1) ti 'L2', '' u 7 ti 'MEM'" >> multicores.gnuplot + done +done + +gnuplot multicores.gnuplot + +for f in *.ps ; do + ps2pdf $f +done + +acroread *.pdf diff --git a/papihighlevel b/papihighlevel index 6d51173..7c0a367 160000 --- a/papihighlevel +++ b/papihighlevel @@ -1 +1 @@ -Subproject commit 6d5117308f78e2ca984691d4440b6a1aa45857b9 +Subproject commit 7c0a36703f5514e19d982b377b6de3b77eadd022 From f3749cb25ddbd41423248148a605b9daf84c03ed Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Tue, 23 Jun 2009 12:56:36 +0200 Subject: [PATCH 19/62] Print results with double precision --- papihighlevel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/papihighlevel b/papihighlevel index 7c0a367..9e6bf11 160000 --- a/papihighlevel +++ b/papihighlevel @@ -1 +1 @@ -Subproject commit 7c0a36703f5514e19d982b377b6de3b77eadd022 +Subproject commit 9e6bf1124a71a161c3176c04717002d19d06e567 From bc3c66027bb3993752855f996e75a98f990c1ef6 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Tue, 23 Jun 2009 13:10:04 +0200 Subject: [PATCH 20/62] Display total time --- communication_techniques/parsing.sh | 2 +- communication_techniques/src/main.c | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/communication_techniques/parsing.sh b/communication_techniques/parsing.sh index b20030f..f5f3b76 100644 --- a/communication_techniques/parsing.sh +++ b/communication_techniques/parsing.sh @@ -7,7 +7,7 @@ comList=`ls *.log | perl -ni -e '/-([^-]+)_comm/; $a{$1}=""; END { foreach ( sor cacheList=`ls *log | perl -ni -e '/cache_([^-]+)-/; $a{$1}=""; END { foreach ( sort keys %a ) {print "$_ "}}'` prodList=`ls *.log | perl -ni -e '/typeProd_([^-]+)-/; $a{$1}=""; END { foreach ( sort keys %a ) {print "$_ "}}'` -metriqueList="cache_hits cache_miss cycles" +metriqueList="cache_hits cache_miss cycles total_time" echo "set style data histogram" > multicores.gnuplot echo "set style histogram cluster gap 1" >> multicores.gnuplot diff --git a/communication_techniques/src/main.c b/communication_techniques/src/main.c index 614b112..8dbdad2 100644 --- a/communication_techniques/src/main.c +++ b/communication_techniques/src/main.c @@ -10,6 +10,7 @@ #include #include #include +#include /* Non standards includes */ #include @@ -177,6 +178,7 @@ int analyse_options(int argc, char *argv[]) void *producer(void *unused) { int i, j; + struct timeval tv1, tv2, tv_result; init_producer_thread(); if (shared) @@ -208,6 +210,7 @@ void *producer(void *unused) } } init_calc(INIT_CALC_ARG); + gettimeofday(&tv1, NULL); if (initialize_papi() != -1) { for(i = 0; i < nb_bufs_sent; i++) { @@ -217,6 +220,18 @@ void *producer(void *unused) } print_results(BUF_SIZE / sizeof(uintptr_t), nb_bufs_sent); } + gettimeofday(&tv2, NULL); + tv_result.tv_sec = tv2.tv_sec - tv1.tv_sec; + if (tv2.tv_usec < tv1.tv_usec) + { + tv_result.tv_usec = tv1.tv_usec - tv2.tv_usec; + tv_result.tv_sec--; + } + else + tv_result.tv_usec = tv2.tv_usec - tv1.tv_usec; + printf("total_time: %u.%6u / %u.%6u / %u.%6u\n", (unsigned) tv_result.tv_sec, (unsigned) tv_result.tv_usec, + (unsigned) tv_result.tv_sec, (unsigned) tv_result.tv_usec, (unsigned) tv_result.tv_sec, + (unsigned) tv_result.tv_usec); end_calc(); printf("[%p] Producer finished !\n", (void*) pthread_self()); /* From 934790a6d955fda9c23319c99855a6bed53cb231 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Tue, 23 Jun 2009 14:46:00 +0200 Subject: [PATCH 22/62] commtechs bench: Print time information --- communication_techniques/parsing.sh | 16 ++++++++++++---- papihighlevel | 2 +- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/communication_techniques/parsing.sh b/communication_techniques/parsing.sh index f5f3b76..1e5a715 100644 --- a/communication_techniques/parsing.sh +++ b/communication_techniques/parsing.sh @@ -26,11 +26,19 @@ for prod in $prodList ; do echo -ne "\n$com\t\t" >> prod_$prod-$metrique.dat done for cache in $cacheList ; do - for metrique in $metriqueList ; do - for value in `perl -n -e "print '$1 $2 $3' if /${metrique}.* (\\d+) \\/ (\\d+) \\/ (\\d+)/" cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do - echo -ne "\t$value " >> prod_$prod-${metrique}.dat - done + for value in `perl -n -e 'print "$1 $2 $3" if /cache hits.* (\d+) \/ (\d+) \/ (\d+)/' cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do + echo -ne "\t$value " >> prod_$prod-cache_hits.dat done + for value in `perl -n -e 'print "$1 $2 $3" if /cache miss.* (\d+) \/ (\d+) \/ (\d+)/' cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do + echo -ne "\t$value" >> prod_$prod-cache_miss.dat + done + for value in `perl -n -e 'print "$1 $2 $3" if /cycles.* (\d+) \/ (\d+) \/ (\d+)/' cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do + echo -ne "\t$value" >> prod_$prod-cycles.dat + done + for value in `perl -n -e 'print "$1 $2 $3" if /total_time.* (\d+) \/ (\d+) \/ (\d+)/' cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do + echo -ne "\t$value" >> prod_$prod-cycles.dat + done + done done for metrique in $metriqueList ; do diff --git a/papihighlevel b/papihighlevel index 9e6bf11..2bb75f2 160000 --- a/papihighlevel +++ b/papihighlevel @@ -1 +1 @@ -Subproject commit 9e6bf1124a71a161c3176c04717002d19d06e567 +Subproject commit 2bb75f2be7e6b7f6de224b3ec0d144ec1805229f From 34faada5fe489aea3d3f8bc905ce3e887dd523c5 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Wed, 24 Jun 2009 00:53:13 +0200 Subject: [PATCH 23/62] commtechs: Correctly parse outputs --- communication_techniques/parsing.sh | 25 ++++++++++++++----------- communication_techniques/src/main.c | 2 +- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/communication_techniques/parsing.sh b/communication_techniques/parsing.sh index 1e5a715..ca82812 100644 --- a/communication_techniques/parsing.sh +++ b/communication_techniques/parsing.sh @@ -26,28 +26,31 @@ for prod in $prodList ; do echo -ne "\n$com\t\t" >> prod_$prod-$metrique.dat done for cache in $cacheList ; do - for value in `perl -n -e 'print "$1 $2 $3" if /cache hits.* (\d+) \/ (\d+) \/ (\d+)/' cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do + for value in `perl -n -e 'print "$1 $2 $3" if /cache hits.* (\d+) \/ (\S+) \/ (\S+)/' cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do echo -ne "\t$value " >> prod_$prod-cache_hits.dat done - for value in `perl -n -e 'print "$1 $2 $3" if /cache miss.* (\d+) \/ (\d+) \/ (\d+)/' cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do + for value in `perl -n -e 'print "$1 $2 $3" if /cache miss.* (\d+) \/ (\S+) \/ (\S+)/' cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do echo -ne "\t$value" >> prod_$prod-cache_miss.dat done - for value in `perl -n -e 'print "$1 $2 $3" if /cycles.* (\d+) \/ (\d+) \/ (\d+)/' cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do + for value in `perl -n -e 'print "$1 $2 $3" if /cycles.* (\d+) \/ (\S+) \/ (\S+)/' cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do echo -ne "\t$value" >> prod_$prod-cycles.dat done - for value in `perl -n -e 'print "$1 $2 $3" if /total_time.* (\d+) \/ (\d+) \/ (\d+)/' cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do - echo -ne "\t$value" >> prod_$prod-cycles.dat + for value in `perl -n -e 'print "$1 $2 $3" if /total_time.* (\S+) \/ (\S+) \/ (\S+)/' cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do + echo -ne "\t$value" >> prod_$prod-total_time.dat done done done for metrique in $metriqueList ; do - echo "set output 'prod_$prod-$metrique-total.ps'" >> multicores.gnuplot - echo "plot 'prod_$prod-$metrique.dat' using 2:xtic(1) ti 'L2', '' u 5 ti 'MEM'" >> multicores.gnuplot - echo "set output 'prod_$prod-$metrique-byLoop.ps'" >> multicores.gnuplot - echo "plot 'prod_$prod-$metrique.dat' using 3:xtic(1) ti 'L2', '' u 6 ti 'MEM'" >> multicores.gnuplot - echo "set output 'prod_$prod-$metrique-byWrite.ps'" >> multicores.gnuplot - echo "plot 'prod_$prod-$metrique.dat' using 4:xtic(1) ti 'L2', '' u 7 ti 'MEM'" >> multicores.gnuplot + for xscale in "nologscale" "logscale" ; do + echo "set $xscale x" >> multicores.gnuplot + echo "set output 'prod_$prod-$metrique-total-$xscale.ps'" >> multicores.gnuplot + echo "plot 'prod_$prod-$metrique.dat' using 2:xtic(1) ti 'L2', '' u 5 ti 'MEM'" >> multicores.gnuplot + echo "set output 'prod_$prod-$metrique-byLoop-$xscale.ps'" >> multicores.gnuplot + echo "plot 'prod_$prod-$metrique.dat' using 3:xtic(1) ti 'L2', '' u 6 ti 'MEM'" >> multicores.gnuplot + echo "set output 'prod_$prod-$metrique-byWrite-$xscale.ps'" >> multicores.gnuplot + echo "plot 'prod_$prod-$metrique.dat' using 4:xtic(1) ti 'L2', '' u 7 ti 'MEM'" >> multicores.gnuplot + done done done diff --git a/communication_techniques/src/main.c b/communication_techniques/src/main.c index 8dbdad2..13f2514 100644 --- a/communication_techniques/src/main.c +++ b/communication_techniques/src/main.c @@ -229,7 +229,7 @@ void *producer(void *unused) } else tv_result.tv_usec = tv2.tv_usec - tv1.tv_usec; - printf("total_time: %u.%6u / %u.%6u / %u.%6u\n", (unsigned) tv_result.tv_sec, (unsigned) tv_result.tv_usec, + printf("total_time: %u.%06u / %u.%06u / %u.%06u\n", (unsigned) tv_result.tv_sec, (unsigned) tv_result.tv_usec, (unsigned) tv_result.tv_sec, (unsigned) tv_result.tv_usec, (unsigned) tv_result.tv_sec, (unsigned) tv_result.tv_usec); end_calc(); From 7177f1c84d11fcee78ca173ee56662eee8471413 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Wed, 24 Jun 2009 00:53:31 +0200 Subject: [PATCH 24/62] Disable debugging info in compilation --- communication_techniques/Makefile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/communication_techniques/Makefile b/communication_techniques/Makefile index 0c724ba..0bdbf00 100644 --- a/communication_techniques/Makefile +++ b/communication_techniques/Makefile @@ -14,7 +14,7 @@ COMMDIR:=communication # Compilation flags # I know -finline-functions and -finline-functions-called-once are enabled by # -O3 but I did this in case gcc behaviour change one day -CFLAGS:=-g -O3 -finline-functions -finline-functions-called-once -Wall -Werror +CFLAGS:=-c -O3 -finline-functions -finline-functions-called-once -Wall -Werror LDFLAGS:=-L$(LIBDIR) -L$(LOCALDIR)/$(PAPIHIGHLEVELLIBDIR) -Wl,-rpath-link,$(HOME)/local/lib -lpthread -lpapihighlevel -ldl # Executables @@ -57,7 +57,7 @@ $(OBJDIR)/$(COMMDIR)/%.o: $(SRCDIR)/$(COMMDIR)/%.c $(INCDIR)/%_comm.h $(INCDIR)/ if [ ! -d $(OBJDIR) ] ; then mkdir $(OBJDIR) ; fi if [ ! -d $(OBJDIR)/$(COMMDIR) ] ; then mkdir $(OBJDIR)/$(COMMDIR) ; fi cd $(INCDIR) ; ln -sfT $*_comm.h specific_comm.h - $(CC) $(CFLAGS) -I$(INCDIR) -c $< -o $@ + $(CC) $(CFLAGS) -I$(INCDIR) $< -o $@ # Rule for compiling common source files using libcomm is at the end of # this file, after the .SECONDEXPANSION target @@ -66,7 +66,7 @@ $(OBJDIR)/$(COMMDIR)/%.o: $(SRCDIR)/$(COMMDIR)/%.c $(INCDIR)/%_comm.h $(INCDIR)/ $(OBJDIR)/$(CALCDIR)/%.o: $(SRCDIR)/$(CALCDIR)/%.c if [ ! -d $(OBJDIR) ] ; then mkdir $(OBJDIR) ; fi if [ ! -d $(OBJDIR)/$(CALCDIR) ] ; then mkdir $(OBJDIR)/$(CALCDIR) ; fi - $(CC) $(CFLAGS) -I$(INCDIR) -c $< -o $@ + $(CC) $(CFLAGS) -I$(INCDIR) $< -o $@ #.%.d: %.c # gcc $(CFLAGS) -MM $^ | sed -e 's/\([^:]*\):\(.*\)/\1 $@: \2 Makefile/' > $@ @@ -102,10 +102,10 @@ $(OBJDIR)/$(COMMDIR)/%.o: $(SRCDIR)/$(COMMDIR)/$$(*F).c $(INCDIR)/$$(*D)_comm.h if [ ! -d $(OBJDIR)/$(COMMDIR) ] ; then mkdir $(OBJDIR)/$(COMMDIR) ; fi if [ ! -d $(OBJDIR)/$(COMMDIR)/$(*D) ] ; then mkdir $(OBJDIR)/$(COMMDIR)/$(*D) ; fi cd $(INCDIR) ; ln -sfT $(*D)_comm.h specific_comm.h - $(CC) $(CFLAGS) -I$(INCDIR) -I$(LOCALDIR)/$(PAPIHIGHLEVELINCDIR) -c $< -o $@ + $(CC) $(CFLAGS) -I$(INCDIR) -I$(LOCALDIR)/$(PAPIHIGHLEVELINCDIR) $< -o $@ $(OBJDIR)/%.o: $(SRCDIR)/$$(*F).c $(INCDIR)/$$(*D)_comm.h $(INCDIR)/commtech.h if [ ! -d $(OBJDIR) ] ; then mkdir $(OBJDIR) ; fi if [ ! -d $(OBJDIR)/$(*D) ] ; then mkdir $(OBJDIR)/$(*D) ; fi cd $(INCDIR) ; ln -sfT $(*D)_comm.h specific_comm.h - $(CC) $(CFLAGS) -I$(INCDIR) -I$(LOCALDIR)/$(PAPIHIGHLEVELINCDIR) -c $< -o $@ + $(CC) $(CFLAGS) -I$(INCDIR) -I$(LOCALDIR)/$(PAPIHIGHLEVELINCDIR) $< -o $@ From e9dc20ecd84d27a6b1b915e15e095d21f77d046c Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Wed, 24 Jun 2009 18:18:05 +0200 Subject: [PATCH 25/62] commtechs bench: time per loop + time per write --- communication_techniques/src/main.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/communication_techniques/src/main.c b/communication_techniques/src/main.c index 13f2514..ff491f6 100644 --- a/communication_techniques/src/main.c +++ b/communication_techniques/src/main.c @@ -21,6 +21,10 @@ #define toString(x) doStringification(x) #define doStringification(x) #x #define INIT_CALC_ARG 16 +#define WORDS_PER_BUF (BUF_SIZE / sizeof(uintptr_t)) +#define DIV_SEC(secs, div) ((unsigned ) (((unsigned) secs) / (unsigned long) (div))) +#define DIV_USEC(nsecs, nusecs, div) ((unsigned) (((unsigned) (nusecs) + 1000000 * \ + ((unsigned ) (nsecs) % (div))) / (unsigned long) (div))) static long nb_bufs_sent = 0; @@ -215,10 +219,10 @@ void *producer(void *unused) { for(i = 0; i < nb_bufs_sent; i++) { //printf("[%p] Send %d new CACHE_LINE\n", (void *) pthread_self(), BUF_SIZE / CACHE_LINE_SIZE); - for(j = 0; j < (BUF_SIZE / sizeof(uintptr_t)); j++) + for(j = 0; j < WORDS_PER_BUF; j++) send(do_calc()); } - print_results(BUF_SIZE / sizeof(uintptr_t), nb_bufs_sent); + print_results(WORDS_PER_BUF, nb_bufs_sent); } gettimeofday(&tv2, NULL); tv_result.tv_sec = tv2.tv_sec - tv1.tv_sec; @@ -229,9 +233,12 @@ void *producer(void *unused) } else tv_result.tv_usec = tv2.tv_usec - tv1.tv_usec; - printf("total_time: %u.%06u / %u.%06u / %u.%06u\n", (unsigned) tv_result.tv_sec, (unsigned) tv_result.tv_usec, - (unsigned) tv_result.tv_sec, (unsigned) tv_result.tv_usec, (unsigned) tv_result.tv_sec, - (unsigned) tv_result.tv_usec); + printf("total_time: %u.%06u / %u.%06u / %u.%06u\n", (unsigned) tv_result.tv_sec, + (unsigned) tv_result.tv_usec, + DIV_SEC(tv_result.tv_sec, nb_bufs_sent), + DIV_USEC(tv_result.tv_sec, tv_result.tv_usec, nb_bufs_sent), + DIV_SEC(tv_result.tv_sec, nb_bufs_sent * WORDS_PER_BUF), + DIV_USEC(tv_result.tv_sec, tv_result.tv_usec, nb_bufs_sent * WORDS_PER_BUF)); end_calc(); printf("[%p] Producer finished !\n", (void*) pthread_self()); /* From 737056ada1ef4e88b83ec9c99c49a91ca9a37bb1 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Wed, 24 Jun 2009 18:27:40 +0200 Subject: [PATCH 26/62] commtechs bench: Logarithmic metric --- communication_techniques/parsing.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/communication_techniques/parsing.sh b/communication_techniques/parsing.sh index ca82812..5cee3d2 100644 --- a/communication_techniques/parsing.sh +++ b/communication_techniques/parsing.sh @@ -42,13 +42,13 @@ for prod in $prodList ; do done done for metrique in $metriqueList ; do - for xscale in "nologscale" "logscale" ; do - echo "set $xscale x" >> multicores.gnuplot - echo "set output 'prod_$prod-$metrique-total-$xscale.ps'" >> multicores.gnuplot + for yscale in "nologscale" "logscale" ; do + echo "set $yscale y" >> multicores.gnuplot + echo "set output 'prod_$prod-$metrique-total-$yscale.ps'" >> multicores.gnuplot echo "plot 'prod_$prod-$metrique.dat' using 2:xtic(1) ti 'L2', '' u 5 ti 'MEM'" >> multicores.gnuplot - echo "set output 'prod_$prod-$metrique-byLoop-$xscale.ps'" >> multicores.gnuplot + echo "set output 'prod_$prod-$metrique-byLoop-$yscale.ps'" >> multicores.gnuplot echo "plot 'prod_$prod-$metrique.dat' using 3:xtic(1) ti 'L2', '' u 6 ti 'MEM'" >> multicores.gnuplot - echo "set output 'prod_$prod-$metrique-byWrite-$xscale.ps'" >> multicores.gnuplot + echo "set output 'prod_$prod-$metrique-byWrite-$yscale.ps'" >> multicores.gnuplot echo "plot 'prod_$prod-$metrique.dat' using 4:xtic(1) ti 'L2', '' u 7 ti 'MEM'" >> multicores.gnuplot done done From 74a0065616aae069b0e11e35c79d292676add558 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Wed, 24 Jun 2009 18:28:27 +0200 Subject: [PATCH 27/62] commtechs bench: Add execute rights on parsing.sh --- communication_techniques/parsing.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 communication_techniques/parsing.sh diff --git a/communication_techniques/parsing.sh b/communication_techniques/parsing.sh old mode 100644 new mode 100755 From ec4bd91021f982fcc2e23b906918c6e77e642b84 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Wed, 24 Jun 2009 18:30:48 +0200 Subject: [PATCH 28/62] commtechs bench: start y at 1 --- communication_techniques/parsing.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/communication_techniques/parsing.sh b/communication_techniques/parsing.sh index 5cee3d2..82a7066 100755 --- a/communication_techniques/parsing.sh +++ b/communication_techniques/parsing.sh @@ -14,6 +14,7 @@ echo "set style histogram cluster gap 1" >> multicores.gnuplot echo "set style fill solid border -1" >> multicores.gnuplot echo "set boxwidth 0.9" >> multicores.gnuplot echo "set xtic rotate by -45" >> multicores.gnuplot +echo "set yrange [1:*]" >> multicores.gnuplot echo "set bmargin 5" >> multicores.gnuplot echo "set terminal postscript landscape color" >> multicores.gnuplot From b58d18cc5d53b40fd55c0494df7b9bdf7e9f547d Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Wed, 24 Jun 2009 20:14:24 +0200 Subject: [PATCH 29/62] commtechs bench: Add title and legends --- communication_techniques/parsing.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/communication_techniques/parsing.sh b/communication_techniques/parsing.sh index 82a7066..7842f20 100755 --- a/communication_techniques/parsing.sh +++ b/communication_techniques/parsing.sh @@ -43,12 +43,24 @@ for prod in $prodList ; do done done for metrique in $metriqueList ; do + case "$metrique" in + cache_hits) ylabel="Nb cache hit" ;; + cache_miss) ylabel="Nb cache miss" ;; + cycles) ylabel="Nb cycles" ;; + total_time) ylabel="Secondes" ;; + *) echo "Pas de label pour cette métrique : $metrique" ; exit 1 ;; + esac + for yscale in "nologscale" "logscale" ; do echo "set $yscale y" >> multicores.gnuplot + echo "set title \"Producteur : $prod\"" >> multicores.gnuplot + echo "set ylabel \"$ylabel\"" >> multicores.gnuplot echo "set output 'prod_$prod-$metrique-total-$yscale.ps'" >> multicores.gnuplot echo "plot 'prod_$prod-$metrique.dat' using 2:xtic(1) ti 'L2', '' u 5 ti 'MEM'" >> multicores.gnuplot + echo "set ylabel \"$ylabel par boucle\"" >> multicores.gnuplot echo "set output 'prod_$prod-$metrique-byLoop-$yscale.ps'" >> multicores.gnuplot echo "plot 'prod_$prod-$metrique.dat' using 3:xtic(1) ti 'L2', '' u 6 ti 'MEM'" >> multicores.gnuplot + echo "set ylabel \"$ylabel par ecriture\"" >> multicores.gnuplot echo "set output 'prod_$prod-$metrique-byWrite-$yscale.ps'" >> multicores.gnuplot echo "plot 'prod_$prod-$metrique.dat' using 4:xtic(1) ti 'L2', '' u 7 ti 'MEM'" >> multicores.gnuplot done From 72db76b9fa538266ee07baef2a60ae990665649d Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Wed, 24 Jun 2009 20:14:50 +0200 Subject: [PATCH 30/62] commtechs bench: Separate bench in 2 benchs --- communication_techniques/parsing.sh | 89 +++++++++++++++-------------- 1 file changed, 47 insertions(+), 42 deletions(-) diff --git a/communication_techniques/parsing.sh b/communication_techniques/parsing.sh index 7842f20..87c697c 100755 --- a/communication_techniques/parsing.sh +++ b/communication_techniques/parsing.sh @@ -6,6 +6,8 @@ set -u comList=`ls *.log | perl -ni -e '/-([^-]+)_comm/; $a{$1}=""; END { foreach ( sort keys %a ) {print "$_ "}}'` cacheList=`ls *log | perl -ni -e '/cache_([^-]+)-/; $a{$1}=""; END { foreach ( sort keys %a ) {print "$_ "}}'` prodList=`ls *.log | perl -ni -e '/typeProd_([^-]+)-/; $a{$1}=""; END { foreach ( sort keys %a ) {print "$_ "}}'` +barriereList="jikes_barrier asm_cache c_cache fake" +communicationList="asm_cache c_cache shared_mem shared_mem_opt pipe" metriqueList="cache_hits cache_miss cycles total_time" @@ -14,58 +16,61 @@ echo "set style histogram cluster gap 1" >> multicores.gnuplot echo "set style fill solid border -1" >> multicores.gnuplot echo "set boxwidth 0.9" >> multicores.gnuplot echo "set xtic rotate by -45" >> multicores.gnuplot -echo "set yrange [1:*]" >> multicores.gnuplot echo "set bmargin 5" >> multicores.gnuplot echo "set terminal postscript landscape color" >> multicores.gnuplot for prod in $prodList ; do - for metrique in $metriqueList ; do - > prod_$prod-$metrique.dat - done - for com in $comList ; do + for bench in "communication" "barriere" ; do for metrique in $metriqueList ; do - echo -ne "\n$com\t\t" >> prod_$prod-$metrique.dat + > $bench-prod_$prod-$metrique.dat done - for cache in $cacheList ; do - for value in `perl -n -e 'print "$1 $2 $3" if /cache hits.* (\d+) \/ (\S+) \/ (\S+)/' cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do - echo -ne "\t$value " >> prod_$prod-cache_hits.dat - done - for value in `perl -n -e 'print "$1 $2 $3" if /cache miss.* (\d+) \/ (\S+) \/ (\S+)/' cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do - echo -ne "\t$value" >> prod_$prod-cache_miss.dat - done - for value in `perl -n -e 'print "$1 $2 $3" if /cycles.* (\d+) \/ (\S+) \/ (\S+)/' cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do - echo -ne "\t$value" >> prod_$prod-cycles.dat - done - for value in `perl -n -e 'print "$1 $2 $3" if /total_time.* (\S+) \/ (\S+) \/ (\S+)/' cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do - echo -ne "\t$value" >> prod_$prod-total_time.dat + for com in `eval echo \\\$\${bench}List` ; do + for metrique in $metriqueList ; do + echo -ne "\n$com\t\t" >> $bench-prod_$prod-$metrique.dat done + for cache in $cacheList ; do + for value in `perl -n -e 'print "$1 $2 $3" if /cache hits.* (\d+) \/ (\S+) \/ (\S+)/' cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do + echo -ne "\t$value " >> $bench-prod_$prod-cache_hits.dat + done + for value in `perl -n -e 'print "$1 $2 $3" if /cache miss.* (\d+) \/ (\S+) \/ (\S+)/' cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do + echo -ne "\t$value" >> $bench-prod_$prod-cache_miss.dat + done + for value in `perl -n -e 'print "$1 $2 $3" if /cycles.* (\d+) \/ (\S+) \/ (\S+)/' cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do + echo -ne "\t$value" >> $bench-prod_$prod-cycles.dat + done + for value in `perl -n -e 'print "$1 $2 $3" if /total_time.* (\S+) \/ (\S+) \/ (\S+)/' cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do + echo -ne "\t$value" >> $bench-prod_$prod-total_time.dat + done + done + done + for metrique in $metriqueList ; do + case "$metrique" in + cache_hits) ylabel="Nb cache hit" ;; + cache_miss) ylabel="Nb cache miss" ;; + cycles) ylabel="Nb cycles" ;; + total_time) ylabel="Secondes" ;; + *) echo "Pas de label pour cette métrique : $metrique" ; exit 1 ;; + esac + + for yscale in "nologscale" "logscale" ; do + echo "set $yscale y" >> multicores.gnuplot + [ "$yscale" = "nologscale" ] && echo "set yrange [0:*]" >> multicores.gnuplot \ + || echo "set yrange [*:*]" >> multicores.gnuplot + echo "set title \"Producteur : $prod\"" >> multicores.gnuplot + echo "set ylabel \"$ylabel\"" >> multicores.gnuplot + echo "set output '$bench-prod_$prod-$metrique-total-$yscale.ps'" >> multicores.gnuplot + echo "plot '$bench-prod_$prod-$metrique.dat' using 2:xtic(1) ti 'L2', '' u 5 ti 'MEM'" >> multicores.gnuplot + echo "set ylabel \"$ylabel par boucle\"" >> multicores.gnuplot + echo "set output '$bench-prod_$prod-$metrique-byLoop-$yscale.ps'" >> multicores.gnuplot + echo "plot '$bench-prod_$prod-$metrique.dat' using 3:xtic(1) ti 'L2', '' u 6 ti 'MEM'" >> multicores.gnuplot + echo "set ylabel \"$ylabel par ecriture\"" >> multicores.gnuplot + echo "set output '$bench-prod_$prod-$metrique-byWrite-$yscale.ps'" >> multicores.gnuplot + echo "plot '$bench-prod_$prod-$metrique.dat' using 4:xtic(1) ti 'L2', '' u 7 ti 'MEM'" >> multicores.gnuplot + done done done - for metrique in $metriqueList ; do - case "$metrique" in - cache_hits) ylabel="Nb cache hit" ;; - cache_miss) ylabel="Nb cache miss" ;; - cycles) ylabel="Nb cycles" ;; - total_time) ylabel="Secondes" ;; - *) echo "Pas de label pour cette métrique : $metrique" ; exit 1 ;; - esac - - for yscale in "nologscale" "logscale" ; do - echo "set $yscale y" >> multicores.gnuplot - echo "set title \"Producteur : $prod\"" >> multicores.gnuplot - echo "set ylabel \"$ylabel\"" >> multicores.gnuplot - echo "set output 'prod_$prod-$metrique-total-$yscale.ps'" >> multicores.gnuplot - echo "plot 'prod_$prod-$metrique.dat' using 2:xtic(1) ti 'L2', '' u 5 ti 'MEM'" >> multicores.gnuplot - echo "set ylabel \"$ylabel par boucle\"" >> multicores.gnuplot - echo "set output 'prod_$prod-$metrique-byLoop-$yscale.ps'" >> multicores.gnuplot - echo "plot 'prod_$prod-$metrique.dat' using 3:xtic(1) ti 'L2', '' u 6 ti 'MEM'" >> multicores.gnuplot - echo "set ylabel \"$ylabel par ecriture\"" >> multicores.gnuplot - echo "set output 'prod_$prod-$metrique-byWrite-$yscale.ps'" >> multicores.gnuplot - echo "plot 'prod_$prod-$metrique.dat' using 4:xtic(1) ti 'L2', '' u 7 ti 'MEM'" >> multicores.gnuplot - done - done -done +done gnuplot multicores.gnuplot From 8f0aecedec098053775c1d95daa3898077dbc8b7 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Wed, 24 Jun 2009 22:25:28 +0200 Subject: [PATCH 31/62] comtechs bench: Better management of errors --- .../include/asm_cache_comm.h | 3 +- .../include/c_cache_comm.h | 3 +- communication_techniques/include/commtech.h | 4 +- communication_techniques/include/fake_comm.h | 3 +- .../include/jikes_barrier_comm.h | 3 +- communication_techniques/include/pipe_comm.h | 3 +- .../include/shared_mem_comm.h | 3 +- .../include/shared_mem_opt_comm.h | 3 +- .../src/calculation/calc_mat.c | 18 ++++- .../src/communication/asm_cache.c | 8 +- .../src/communication/c_cache.c | 8 +- .../src/communication/common.c | 35 +++++--- .../src/communication/fake.c | 8 +- .../src/communication/jikes_barrier.c | 13 ++- .../src/communication/pipe.c | 8 +- .../src/communication/shared_mem.c | 8 +- .../src/communication/shared_mem_opt.c | 8 +- communication_techniques/src/main.c | 81 ++++++++++++++----- 18 files changed, 171 insertions(+), 49 deletions(-) diff --git a/communication_techniques/include/asm_cache_comm.h b/communication_techniques/include/asm_cache_comm.h index d6b7c95..19a75ca 100644 --- a/communication_techniques/include/asm_cache_comm.h +++ b/communication_techniques/include/asm_cache_comm.h @@ -27,7 +27,8 @@ struct thread_comm extern struct thread_comm *tcomms; extern int swap_buffer; -void init_thread_comm(struct thread_comm *); +int init_thread_comm(struct thread_comm *); +int end_thread_comm(void); static inline void send(void **addr) { asm volatile("mov %%gs:channel@NTPOFF + 2 *" toString(BUF_SIZE) " + " toString(CACHE_LINE_SIZE) ", %%eax\n\t" diff --git a/communication_techniques/include/c_cache_comm.h b/communication_techniques/include/c_cache_comm.h index 49d39af..c11ce07 100644 --- a/communication_techniques/include/c_cache_comm.h +++ b/communication_techniques/include/c_cache_comm.h @@ -26,7 +26,8 @@ extern __thread struct comm_channel channel; __BEGIN_DECLS -void init_thread_comm(struct thread_comm *); +int init_thread_comm(struct thread_comm *); +int end_thread_comm(void); static inline void send(void **addr) { channel.buf[channel.idx++] = addr; diff --git a/communication_techniques/include/commtech.h b/communication_techniques/include/commtech.h index 539c977..f0deb87 100644 --- a/communication_techniques/include/commtech.h +++ b/communication_techniques/include/commtech.h @@ -13,7 +13,9 @@ extern long nb_prod; __BEGIN_DECLS int init_library(void); -void init_producer_thread(void); +int end_library(void); +int init_producer_thread(void); +int end_producer_thread(void); void reception(void (*)(void *)); __END_DECLS diff --git a/communication_techniques/include/fake_comm.h b/communication_techniques/include/fake_comm.h index fad7f07..b0d85a6 100644 --- a/communication_techniques/include/fake_comm.h +++ b/communication_techniques/include/fake_comm.h @@ -12,7 +12,8 @@ extern struct thread_comm *tcomms; __BEGIN_DECLS -void init_thread_comm(struct thread_comm *); +int init_thread_comm(struct thread_comm *); +int end_thread_comm(void); static inline void send(void **addr) { static __thread void **store_var = NULL; store_var = addr; diff --git a/communication_techniques/include/jikes_barrier_comm.h b/communication_techniques/include/jikes_barrier_comm.h index 4cf541d..803482d 100644 --- a/communication_techniques/include/jikes_barrier_comm.h +++ b/communication_techniques/include/jikes_barrier_comm.h @@ -15,7 +15,8 @@ extern struct thread_comm *tcomms; __BEGIN_DECLS -void init_thread_comm(struct thread_comm *); +int init_thread_comm(struct thread_comm *); +int end_thread_comm(void); void insert(void *); static inline void send(void **addr) { diff --git a/communication_techniques/include/pipe_comm.h b/communication_techniques/include/pipe_comm.h index 620000a..f5e4150 100644 --- a/communication_techniques/include/pipe_comm.h +++ b/communication_techniques/include/pipe_comm.h @@ -16,7 +16,8 @@ __BEGIN_DECLS extern __thread int pipefd[]; extern struct thread_comm *tcomms; -void init_thread_comm(struct thread_comm *); +int init_thread_comm(struct thread_comm *); +int end_thread_comm(void); static inline void send(void **addr) { write(pipefd[WRITE_IDX], &addr, sizeof(void *)); } diff --git a/communication_techniques/include/shared_mem_comm.h b/communication_techniques/include/shared_mem_comm.h index f9d4214..0bee7d7 100644 --- a/communication_techniques/include/shared_mem_comm.h +++ b/communication_techniques/include/shared_mem_comm.h @@ -22,7 +22,8 @@ extern __thread volatile void **shared_space; extern __thread volatile int prod_idx; extern __thread volatile int cons_idx; -void init_thread_comm(struct thread_comm *); +int init_thread_comm(struct thread_comm *); +int end_thread_comm(void); static inline void send(void **addr) { while ((prod_idx + 1) % SHARED_SPACE_VOIDPTR == cons_idx); shared_space[prod_idx] = addr; diff --git a/communication_techniques/include/shared_mem_opt_comm.h b/communication_techniques/include/shared_mem_opt_comm.h index 6126004..5184c73 100644 --- a/communication_techniques/include/shared_mem_opt_comm.h +++ b/communication_techniques/include/shared_mem_opt_comm.h @@ -22,7 +22,8 @@ extern __thread volatile void **shared_space; extern __thread volatile int prod_idx; extern __thread volatile int cons_idx; -void init_thread_comm(struct thread_comm *); +int init_thread_comm(struct thread_comm *); +int end_thread_comm(void); static inline void send(void **addr) { static __thread int local_cons_idx = 0; diff --git a/communication_techniques/src/calculation/calc_mat.c b/communication_techniques/src/calculation/calc_mat.c index 149c7e5..f3044de 100644 --- a/communication_techniques/src/calculation/calc_mat.c +++ b/communication_techniques/src/calculation/calc_mat.c @@ -1,4 +1,5 @@ #include +#include #define likely(x) __builtin_expect(!!(x), 1) @@ -9,7 +10,7 @@ static int *mat, *vect; static int li; static int n, m; /* Size of the matrice: n lines, m columns */ -void init_calc(int size) +int init_calc(int size) { int i; @@ -17,10 +18,22 @@ void init_calc(int size) m = size; srand(42); mat = (int *) malloc(n * m * sizeof(int)); + if (mat == NULL) + { + fprintf(stderr, "calc_mat: Unable to allocate memory for matrice calculation\n"); + return -1; + } vect = (int *) malloc(m * sizeof(int)); + if (vect == NULL) + { + free(mat); + fprintf(stderr, "calc_mat: Unable to allocate memory for matrice calculation\n"); + return -1; + } for (i = 0; i < n * m; i++) mat[i] = rand(); li = 0; + return 0; } void *do_calc(void) @@ -35,8 +48,9 @@ void *do_calc(void) return &mat[li * m]; } -void end_calc(void) +int end_calc(void) { free(mat); free(vect); + return 0; } diff --git a/communication_techniques/src/communication/asm_cache.c b/communication_techniques/src/communication/asm_cache.c index bf4589a..4a49dad 100644 --- a/communication_techniques/src/communication/asm_cache.c +++ b/communication_techniques/src/communication/asm_cache.c @@ -10,12 +10,18 @@ __thread struct comm_channel channel; -void init_thread_comm(struct thread_comm *comm) +int init_thread_comm(struct thread_comm *comm) { comm->receiver_idx = 0; comm->channel = &channel; comm->channel->state = 0; comm->channel->idx = 0; + return 0; +} + +int end_thread_comm(void) +{ + return 0; } char *dstr="buffer transition\n"; diff --git a/communication_techniques/src/communication/c_cache.c b/communication_techniques/src/communication/c_cache.c index 42f081d..b310595 100644 --- a/communication_techniques/src/communication/c_cache.c +++ b/communication_techniques/src/communication/c_cache.c @@ -10,12 +10,18 @@ __thread struct comm_channel channel; -void init_thread_comm(struct thread_comm *comm) +int init_thread_comm(struct thread_comm *comm) { comm->receiver_idx = 0; comm->channel = &channel; comm->channel->state = 0; comm->channel->idx = 0; + return 0; +} + +int end_thread_comm(void) +{ + return 0; } char *dstr="buffer transition\n"; diff --git a/communication_techniques/src/communication/common.c b/communication_techniques/src/communication/common.c index e7a7cca..4c4e39d 100644 --- a/communication_techniques/src/communication/common.c +++ b/communication_techniques/src/communication/common.c @@ -11,6 +11,7 @@ struct thread_comm *tcomms; volatile int cont = 1; static int init = 0; +static int error = 0; static pthread_mutex_t init_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t init_cond = PTHREAD_COND_INITIALIZER; @@ -25,6 +26,12 @@ int init_library(void) return 0; } +int end_library(void) +{ + free(tcomms); + return 0; +} + int get_thread_number(void) { static int i = 0; @@ -38,27 +45,35 @@ int get_thread_number(void) return i_local; } -void init_producer_thread(void) +int init_producer_thread(void) { - static int i = 0; - static pthread_mutex_t i_lock = PTHREAD_MUTEX_INITIALIZER; int i_local; - pthread_mutex_lock(&i_lock); - i_local = i; - i++; - pthread_mutex_unlock(&i_lock); - init_thread_comm(&tcomms[i_local]); + i_local = get_thread_number(); + if (init_thread_comm(&tcomms[i_local])) + { + error = 1; + return -1; + } pthread_mutex_lock(&init_lock); init = 1; pthread_cond_signal(&init_cond); pthread_mutex_unlock(&init_lock); + return 0; } -void wait_initialization(void) +int end_producer_thread(void) +{ + return end_thread_comm(); +} + +int wait_initialization(void) { pthread_mutex_lock(&init_lock); - if (!init) + if (!init && !error) pthread_cond_wait(&init_cond, &init_lock); pthread_mutex_unlock(&init_lock); + if (error) + return -1; + return 0; } diff --git a/communication_techniques/src/communication/fake.c b/communication_techniques/src/communication/fake.c index 68792f5..c92192c 100644 --- a/communication_techniques/src/communication/fake.c +++ b/communication_techniques/src/communication/fake.c @@ -9,8 +9,14 @@ #include -void init_thread_comm(struct thread_comm *comm) +int init_thread_comm(struct thread_comm *comm) { + return 0; +} + +int end_thread_comm(void) +{ + return 0; } void reception(void (*on_receive)(void *)) diff --git a/communication_techniques/src/communication/jikes_barrier.c b/communication_techniques/src/communication/jikes_barrier.c index e232797..0df0aea 100644 --- a/communication_techniques/src/communication/jikes_barrier.c +++ b/communication_techniques/src/communication/jikes_barrier.c @@ -33,14 +33,25 @@ static struct double_linked_list *global_head = NULL; static int bufsenqueued = 0; static unsigned int lock = 0; -void init_thread_comm(struct thread_comm *comm) +int init_thread_comm(struct thread_comm *comm) { void **new_buffer; new_buffer = (void **) malloc(BUFFER_SIZE); + if (new_buffer == NULL) + { + fprintf(stderr, "Failed to allocate a new buffer for the thread\n"); + return -1; + } local_tail = new_buffer + (USABLE_BUFFER_BYTES - BYTES_IN_ADDRESS - (USABLE_BUFFER_BYTES % (1 << LOG_BYTES_IN_ADDRESS))) + BYTES_IN_ADDRESS; // The second parenthesis is equal to 0 local_tail_buffer_end = local_tail; + return 0; +} + +int end_thread_comm(void) +{ + return 0; } void set_next(struct double_linked_list *list, struct double_linked_list *next) diff --git a/communication_techniques/src/communication/pipe.c b/communication_techniques/src/communication/pipe.c index dbec091..6172b79 100644 --- a/communication_techniques/src/communication/pipe.c +++ b/communication_techniques/src/communication/pipe.c @@ -13,7 +13,7 @@ __thread int pipefd[2]; -void init_thread_comm(struct thread_comm *comm) +int init_thread_comm(struct thread_comm *comm) { int flags; @@ -21,6 +21,12 @@ void init_thread_comm(struct thread_comm *comm) flags = fcntl(pipefd[READ_IDX], F_GETFL); fcntl(pipefd[READ_IDX], F_SETFL, flags | O_NONBLOCK); comm->pipefd = pipefd; + return 0; +} + +int end_thread_comm(void) +{ + return 0; } void reception(void (*on_receive)(void *)) diff --git a/communication_techniques/src/communication/shared_mem.c b/communication_techniques/src/communication/shared_mem.c index 0487236..d0a13b3 100644 --- a/communication_techniques/src/communication/shared_mem.c +++ b/communication_techniques/src/communication/shared_mem.c @@ -13,12 +13,18 @@ __thread volatile void **shared_space; __thread volatile int cons_idx = 0; __thread volatile int prod_idx = 0; -void init_thread_comm(struct thread_comm *comm) +int init_thread_comm(struct thread_comm *comm) { shared_space = (volatile void **) malloc(SHARED_SPACE_SIZE); comm->shared_space = shared_space; comm->cons_idx = &cons_idx; comm->prod_idx = &prod_idx; + return 0; +} + +int end_thread_comm(void) +{ + return 0; } void reception(void (*on_receive)(void *)) diff --git a/communication_techniques/src/communication/shared_mem_opt.c b/communication_techniques/src/communication/shared_mem_opt.c index 127e556..0be430a 100644 --- a/communication_techniques/src/communication/shared_mem_opt.c +++ b/communication_techniques/src/communication/shared_mem_opt.c @@ -13,12 +13,18 @@ __thread volatile void **shared_space; __thread volatile int cons_idx = 0; __thread volatile int prod_idx = 0; -void init_thread_comm(struct thread_comm *comm) +int init_thread_comm(struct thread_comm *comm) { shared_space = (volatile void **) malloc(SHARED_SPACE_SIZE); comm->shared_space = shared_space; comm->cons_idx = &cons_idx; comm->prod_idx = &prod_idx; + return 0; +} + +int end_thread_comm(void) +{ + return 0; } void reception(void (*on_receive)(void *)) diff --git a/communication_techniques/src/main.c b/communication_techniques/src/main.c index ff491f6..7a7bc8e 100644 --- a/communication_techniques/src/main.c +++ b/communication_techniques/src/main.c @@ -29,9 +29,9 @@ static long nb_bufs_sent = 0; long nb_prod = 0; -static void (*init_calc)(int) = NULL; +static int (*init_calc)(int) = NULL; static void *(*do_calc)(void) = NULL; -static void (*end_calc)(void) = NULL; +static int (*end_calc)(void) = NULL; static int shared = 0; pthread_cond_t cond_cons_has_finished = PTHREAD_COND_INITIALIZER; pthread_mutex_t mutex_cons_has_finished = PTHREAD_MUTEX_INITIALIZER; @@ -55,8 +55,9 @@ void usage(char *argv[]) printf("%s\n", options); } -void do_noinit(int unused) +int do_noinit(int unused) { + return 0; } void *do_nocalc(void) @@ -66,8 +67,9 @@ void *do_nocalc(void) return &an_int; } -void do_noend(void) +int do_noend(void) { + return 0; } int analyse_options(int argc, char *argv[]) @@ -179,12 +181,27 @@ int analyse_options(int argc, char *argv[]) return 0; } +void wait_consumer(void) +{ + pthread_mutex_lock(&mutex_cons_has_finished); + if (++producers_ended == nb_prod) + cont = 0; + if (!consumer_has_finished) + pthread_cond_wait(&cond_cons_has_finished, &mutex_cons_has_finished); + pthread_mutex_unlock(&mutex_cons_has_finished); +} + void *producer(void *unused) { int i, j; struct timeval tv1, tv2, tv_result; - init_producer_thread(); + if (init_producer_thread()) + { + fprintf(stderr, "Initialization of thread has failed\n"); + wait_consumer(); + return &nb_prod; /* &nb_prod can't be NULL, whatever NULL is bound to */ + } if (shared) { pthread_t tid; @@ -196,7 +213,8 @@ void *producer(void *unused) if (pthread_setaffinity_np(tid, sizeof(cpu_set_t), &cpuset)) { perror("pthread_setaffinity_np"); - return NULL; + wait_consumer(); + return &nb_prod; /* &nb_prod can't be NULL, whatever NULL is bound to */ } } else @@ -210,10 +228,16 @@ void *producer(void *unused) if (pthread_setaffinity_np(tid, sizeof(cpu_set_t), &cpuset)) { perror("pthread_setaffinity_np"); - return NULL; + wait_consumer(); + return &nb_prod; /* &nb_prod can't be NULL, whatever NULL is bound to */ } } - init_calc(INIT_CALC_ARG); + if (init_calc(INIT_CALC_ARG)) + { + fprintf(stderr, "Initialization of calculation has failed\n"); + wait_consumer(); + return &nb_prod; /* nb_prod can't be NULL, whatever NULL is bound to */ + } gettimeofday(&tv1, NULL); if (initialize_papi() != -1) { @@ -234,23 +258,28 @@ void *producer(void *unused) else tv_result.tv_usec = tv2.tv_usec - tv1.tv_usec; printf("total_time: %u.%06u / %u.%06u / %u.%06u\n", (unsigned) tv_result.tv_sec, - (unsigned) tv_result.tv_usec, - DIV_SEC(tv_result.tv_sec, nb_bufs_sent), - DIV_USEC(tv_result.tv_sec, tv_result.tv_usec, nb_bufs_sent), - DIV_SEC(tv_result.tv_sec, nb_bufs_sent * WORDS_PER_BUF), - DIV_USEC(tv_result.tv_sec, tv_result.tv_usec, nb_bufs_sent * WORDS_PER_BUF)); - end_calc(); + (unsigned) tv_result.tv_usec, + DIV_SEC(tv_result.tv_sec, nb_bufs_sent), + DIV_USEC(tv_result.tv_sec, tv_result.tv_usec, nb_bufs_sent), + DIV_SEC(tv_result.tv_sec, nb_bufs_sent * WORDS_PER_BUF), + DIV_USEC(tv_result.tv_sec, tv_result.tv_usec, nb_bufs_sent * WORDS_PER_BUF)); + if (end_calc()) + { + fprintf(stderr, "uninitialization of calculation has failed\n"); + wait_consumer(); + return &nb_prod; /* &nb_prod can't be NULL, whatever NULL is bound to */ + } printf("[%p] Producer finished !\n", (void*) pthread_self()); /* * When a producer end its thread-local storage vanished. Thus, * producers must finish only after consumer has stopped using them */ - pthread_mutex_lock(&mutex_cons_has_finished); - if (++producers_ended == nb_prod) - cont = 0; - if (!consumer_has_finished) - pthread_cond_wait(&cond_cons_has_finished, &mutex_cons_has_finished); - pthread_mutex_unlock(&mutex_cons_has_finished); + wait_consumer(); + if (end_producer_thread()) + { + fprintf(stderr, "Uninitialization of thread has failed\n"); + return &nb_prod; /* &nb_prod can't be NULL, whatever NULL is bound to */ + } return NULL; } @@ -285,7 +314,7 @@ void *receptor(void *a) int main(int argc, char *argv[]) { - int i; + int i, global_return_value = EXIT_SUCCESS; void *return_value; pthread_t *tid; @@ -303,8 +332,16 @@ int main(int argc, char *argv[]) pthread_create(&tid[i], NULL, producer, NULL); pthread_create(&tid[i], NULL, receptor, NULL); for(i = 0; i < nb_prod; i++) + { pthread_join(tid[i], &return_value); + if (return_value != NULL) + global_return_value = EXIT_FAILURE; + } pthread_join(tid[i], &return_value); + if (return_value != NULL) + global_return_value = EXIT_FAILURE; free(tid); - return EXIT_SUCCESS; + if (end_library()) + return EXIT_FAILURE; + return global_return_value; } From 2fe89da8a254877b304fc6238c3b4d2c50041db2 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Wed, 24 Jun 2009 23:16:30 +0200 Subject: [PATCH 32/62] free memory after 100 Mo allocated --- .../src/communication/jikes_barrier.c | 52 +++++++++++++++---- 1 file changed, 42 insertions(+), 10 deletions(-) diff --git a/communication_techniques/src/communication/jikes_barrier.c b/communication_techniques/src/communication/jikes_barrier.c index 0df0aea..0676975 100644 --- a/communication_techniques/src/communication/jikes_barrier.c +++ b/communication_techniques/src/communication/jikes_barrier.c @@ -30,6 +30,7 @@ static __thread void **local_tail = NULL; static __thread void **local_tail_buffer_end = NULL; static struct double_linked_list *global_tail = NULL; static struct double_linked_list *global_head = NULL; +static int collect = 0; static int bufsenqueued = 0; static unsigned int lock = 0; @@ -44,7 +45,7 @@ int init_thread_comm(struct thread_comm *comm) return -1; } local_tail = new_buffer + (USABLE_BUFFER_BYTES - BYTES_IN_ADDRESS - - (USABLE_BUFFER_BYTES % (1 << LOG_BYTES_IN_ADDRESS))) + BYTES_IN_ADDRESS; // The second parenthesis is equal to 0 + (USABLE_BUFFER_BYTES % (1 << LOG_BYTES_IN_ADDRESS))) + BYTES_IN_ADDRESS; /* The second parenthesis is equal to 0 */ local_tail_buffer_end = local_tail; return 0; } @@ -93,7 +94,7 @@ static void spin_unlock(unsigned int *lock) : "memory", "cc"); } -void enqueue(struct double_linked_list *list, int arity, int to_tail) // Insert in the shared buffer: tail here is the tail of the shared buffer +void enqueue(struct double_linked_list *list, int arity, int to_tail) /* Insert in the shared buffer: tail here is the tail of the shared buffer */ { spin_lock(&lock); if (to_tail) @@ -135,34 +136,60 @@ void **normalizeTail(int arity) src++; buffer_start++; } - return last; // Return the buffer address of the last address (if address goes from 0 to n then it's &buf[n] + return last; /* Return the buffer address of the last address (if address goes from 0 to n then it's &buf[n] */ } void closeAndEnqueueTail(int arity) { void **last; - if ((((uintptr_t) local_tail) & BUFFER_MASK) != 0) // prematurely closed, won't pass here if it comes from insert + if ((((uintptr_t) local_tail) & BUFFER_MASK) != 0) /* prematurely closed, won't pass here if it comes from insert */ last = normalizeTail(arity); - else // a full tail buffer - last = local_tail_buffer_end - BYTES_IN_ADDRESS; // last space in the buffer before the 8/16 bytes of metadata of the buffer + else /* a full tail buffer */ + last = local_tail_buffer_end - BYTES_IN_ADDRESS; /* last space in the buffer before the 8/16 bytes of metadata of the buffer */ enqueue((struct double_linked_list *) ((uintptr_t) last + BYTES_IN_ADDRESS), arity, 1); } void checkForAsyncCollection(void) { + if (bufsenqueued >= 102400) /* We use more than 100 Mo */ + collect = 1; +} + +void free_pages(struct double_linked_list *list_cur) +{ + if (list_cur == NULL) + return; + spin_lock(&lock); + /* + * We may free some buffer allocated after this line is executed, thus + * the real number of buffer enqueued could be bigger. + * This is done to avoid to keep the lock during the while loop and for + * checkForAsyncCollection to first start asking for a collection at + * 100 Mo in the *worst* case + */ + bufsenqueued = 0; + spin_unlock(&lock); + while (global_head != list_cur) /* We know closeAndEnqueueTail() ask enqueue() to enqueue at tail */ + { + void *buf_start; + + buf_start = (void *) ((uintptr_t) global_head & BUFFER_MASK); + global_head = global_head->next; + free(buf_start); + } } void tailOverflow(int arity) { void *new_buffer; if (local_tail != NULL) - closeAndEnqueueTail(arity); // Add the buffer to the tail of the shared buffer + closeAndEnqueueTail(arity); /* Add the buffer to the tail of the shared buffer */ if (posix_memalign(&new_buffer, BUFFER_SIZE, BUFFER_SIZE)) fprintf(stderr, "Failed to allocate space for queue. Is metadata virtual memory exhausted?"); local_tail = (void **) ((uintptr_t) new_buffer + (USABLE_BUFFER_BYTES - BYTES_IN_ADDRESS - - (USABLE_BUFFER_BYTES % (arity << LOG_BYTES_IN_ADDRESS))) + BYTES_IN_ADDRESS); // The second parenthesis is equal to 0 + (USABLE_BUFFER_BYTES % (arity << LOG_BYTES_IN_ADDRESS))) + BYTES_IN_ADDRESS); /* The second parenthesis is equal to 0 */ local_tail_buffer_end = local_tail; - checkForAsyncCollection(); // possible side-effect of alloc() + checkForAsyncCollection(); /* possible side-effect of posix_memalign() */ } void insert(void *addr) @@ -175,8 +202,8 @@ void insert(void *addr) void reception(void (*on_receive)(void *)) { - struct double_linked_list *list_cur; void **buf_start, **buf_ptr; + struct double_linked_list *list_cur = NULL; wait_initialization(); /* Not needed but here for equity with others techniques */ /* printf("Activate the consumer...\n"); */ @@ -189,6 +216,11 @@ void reception(void (*on_receive)(void *)) buf_start = (void **) (((uintptr_t) &list_cur->prev) & ~BUFFER_MASK); for (buf_ptr = buf_start; buf_ptr != (void **) &list_cur->prev; buf_ptr++) on_receive(*buf_ptr); + if (collect) + { + free_pages(list_cur); + collect = 0; + } while (cont && (list_cur->next == NULL)); } while (cont); } From 177e548efedf7110999f476e1f4e92672e5e3f6c Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Wed, 24 Jun 2009 23:35:58 +0200 Subject: [PATCH 33/62] commtechs benchs: fake_comm perform the writes --- communication_techniques/include/fake_comm.h | 2 +- communication_techniques/src/communication/fake.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/communication_techniques/include/fake_comm.h b/communication_techniques/include/fake_comm.h index b0d85a6..ac9f3c2 100644 --- a/communication_techniques/include/fake_comm.h +++ b/communication_techniques/include/fake_comm.h @@ -9,13 +9,13 @@ struct thread_comm }; extern struct thread_comm *tcomms; +extern __thread void ** volatile store_var; __BEGIN_DECLS int init_thread_comm(struct thread_comm *); int end_thread_comm(void); static inline void send(void **addr) { - static __thread void **store_var = NULL; store_var = addr; } diff --git a/communication_techniques/src/communication/fake.c b/communication_techniques/src/communication/fake.c index c92192c..ffd72c3 100644 --- a/communication_techniques/src/communication/fake.c +++ b/communication_techniques/src/communication/fake.c @@ -9,6 +9,9 @@ #include +__thread void ** volatile store_var = NULL; + + int init_thread_comm(struct thread_comm *comm) { return 0; From c9323cd90185c4c3521e4680c54e37b9ca651a96 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Thu, 25 Jun 2009 13:42:41 +0200 Subject: [PATCH 34/62] BUGFIX: Fix a possible deadlock if an error occurs --- communication_techniques/src/communication/common.c | 7 ++++--- communication_techniques/src/communication/pipe.c | 6 +++++- communication_techniques/src/communication/shared_mem.c | 5 +++++ .../src/communication/shared_mem_opt.c | 5 +++++ 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/communication_techniques/src/communication/common.c b/communication_techniques/src/communication/common.c index 4c4e39d..900f027 100644 --- a/communication_techniques/src/communication/common.c +++ b/communication_techniques/src/communication/common.c @@ -47,12 +47,13 @@ int get_thread_number(void) int init_producer_thread(void) { - int i_local; + int thread_num; - i_local = get_thread_number(); - if (init_thread_comm(&tcomms[i_local])) + thread_num = get_thread_number(); + if (init_thread_comm(&tcomms[thread_num])) { error = 1; + pthread_cond_signal(&init_cond); return -1; } pthread_mutex_lock(&init_lock); diff --git a/communication_techniques/src/communication/pipe.c b/communication_techniques/src/communication/pipe.c index 6172b79..e903954 100644 --- a/communication_techniques/src/communication/pipe.c +++ b/communication_techniques/src/communication/pipe.c @@ -17,7 +17,11 @@ int init_thread_comm(struct thread_comm *comm) { int flags; - pipe(pipefd); + if (pipe(pipefd)) + { + fprintf(stderr, "Unable to create a pipe for pipe communication\n"); + return -1; + } flags = fcntl(pipefd[READ_IDX], F_GETFL); fcntl(pipefd[READ_IDX], F_SETFL, flags | O_NONBLOCK); comm->pipefd = pipefd; diff --git a/communication_techniques/src/communication/shared_mem.c b/communication_techniques/src/communication/shared_mem.c index d0a13b3..e96c5f9 100644 --- a/communication_techniques/src/communication/shared_mem.c +++ b/communication_techniques/src/communication/shared_mem.c @@ -16,6 +16,11 @@ __thread volatile int prod_idx = 0; int init_thread_comm(struct thread_comm *comm) { shared_space = (volatile void **) malloc(SHARED_SPACE_SIZE); + if (shared_space == NULL) + { + fprintf(stderr, "Unable to allocate space for shared mem communication\n"); + return -1; + } comm->shared_space = shared_space; comm->cons_idx = &cons_idx; comm->prod_idx = &prod_idx; diff --git a/communication_techniques/src/communication/shared_mem_opt.c b/communication_techniques/src/communication/shared_mem_opt.c index 0be430a..df726c7 100644 --- a/communication_techniques/src/communication/shared_mem_opt.c +++ b/communication_techniques/src/communication/shared_mem_opt.c @@ -16,6 +16,11 @@ __thread volatile int prod_idx = 0; int init_thread_comm(struct thread_comm *comm) { shared_space = (volatile void **) malloc(SHARED_SPACE_SIZE); + if (shared_space == NULL) + { + fprintf(stderr, "Unable to allocate space for shared mem communication\n"); + return -1; + } comm->shared_space = shared_space; comm->cons_idx = &cons_idx; comm->prod_idx = &prod_idx; From 6b9777cb9bdd646ce87e5fc57315146d23fa628f Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Thu, 25 Jun 2009 14:01:18 +0200 Subject: [PATCH 35/62] Align shared_mem and initial jikes buffer --- communication_techniques/src/communication/jikes_barrier.c | 3 +-- communication_techniques/src/communication/shared_mem.c | 3 +-- communication_techniques/src/communication/shared_mem_opt.c | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/communication_techniques/src/communication/jikes_barrier.c b/communication_techniques/src/communication/jikes_barrier.c index 0676975..4c0c45a 100644 --- a/communication_techniques/src/communication/jikes_barrier.c +++ b/communication_techniques/src/communication/jikes_barrier.c @@ -38,8 +38,7 @@ int init_thread_comm(struct thread_comm *comm) { void **new_buffer; - new_buffer = (void **) malloc(BUFFER_SIZE); - if (new_buffer == NULL) + if (posix_memalign((void *) &new_buffer, CACHE_LINE_SIZE, BUFFER_SIZE)) { fprintf(stderr, "Failed to allocate a new buffer for the thread\n"); return -1; diff --git a/communication_techniques/src/communication/shared_mem.c b/communication_techniques/src/communication/shared_mem.c index e96c5f9..0ca39d1 100644 --- a/communication_techniques/src/communication/shared_mem.c +++ b/communication_techniques/src/communication/shared_mem.c @@ -15,8 +15,7 @@ __thread volatile int prod_idx = 0; int init_thread_comm(struct thread_comm *comm) { - shared_space = (volatile void **) malloc(SHARED_SPACE_SIZE); - if (shared_space == NULL) + if (posix_memalign((void *) &shared_space, CACHE_LINE_SIZE, SHARED_SPACE_SIZE)) { fprintf(stderr, "Unable to allocate space for shared mem communication\n"); return -1; diff --git a/communication_techniques/src/communication/shared_mem_opt.c b/communication_techniques/src/communication/shared_mem_opt.c index df726c7..64e58ad 100644 --- a/communication_techniques/src/communication/shared_mem_opt.c +++ b/communication_techniques/src/communication/shared_mem_opt.c @@ -15,8 +15,7 @@ __thread volatile int prod_idx = 0; int init_thread_comm(struct thread_comm *comm) { - shared_space = (volatile void **) malloc(SHARED_SPACE_SIZE); - if (shared_space == NULL) + if (posix_memalign((void *) &shared_space, CACHE_LINE_SIZE, SHARED_SPACE_SIZE)) { fprintf(stderr, "Unable to allocate space for shared mem communication\n"); return -1; From a29aafe25e24ef76003394fd20b6a9d0e5b1222a Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Thu, 25 Jun 2009 16:44:46 +0200 Subject: [PATCH 36/62] Makefile is able to use papi libs not installed --- communication_techniques/Makefile | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/communication_techniques/Makefile b/communication_techniques/Makefile index 0bdbf00..acdb948 100644 --- a/communication_techniques/Makefile +++ b/communication_techniques/Makefile @@ -6,8 +6,17 @@ INCDIR:=include LIBDIR:=lib LOGDIR:=logs LOCALDIR:=$(HOME)/local -PAPIHIGHLEVELLIBDIR:=lib -PAPIHIGHLEVELINCDIR:=include + +# PHL stands for PAPI High Level +PHL_LIB_INSTALLDIR:=lib +PHL_INC_INSTALLDIR:=lib +PHL_LIBDIR:=lib +PHL_INCDIR:=include +PHLDIR:=../papihighlevel +PAPI_LIB_INSTALLDIR:=lib +PAPIDIR:=$(PHLDIR)/papi +PAPI_LIBDIR:=src +PAPI_PFMDIR:=$(PAPI_LIBDIR)/libpfm-3.y/lib CALCDIR:=calculation COMMDIR:=communication @@ -15,7 +24,9 @@ COMMDIR:=communication # I know -finline-functions and -finline-functions-called-once are enabled by # -O3 but I did this in case gcc behaviour change one day CFLAGS:=-c -O3 -finline-functions -finline-functions-called-once -Wall -Werror -LDFLAGS:=-L$(LIBDIR) -L$(LOCALDIR)/$(PAPIHIGHLEVELLIBDIR) -Wl,-rpath-link,$(HOME)/local/lib -lpthread -lpapihighlevel -ldl +LDFLAGS:=-L$(LIBDIR) -L$(LOCALDIR)/$(PHL_LIB_INSTALLDIR) -L$(PHLDIR)/$(PHL_LIBDIR) +LDFLAGS:=$(LDFLAGS) -Wl,-rpath-link,$(LOCALDIR)/$(PAPI_LIB_INSTALLDIR):$(PAPIDIR)/$(PAPI_LIBDIR):$(PAPIDIR)/$(PAPI_PFMDIR) +LDFLAGS:=$(LDFLAGS) -lpthread -lpapihighlevel -ldl # Executables CC=gcc @@ -49,7 +60,7 @@ $(LIBDIR)/$(COMMDIR)/lib%.a: $(OBJDIR)/$(COMMDIR)/%.o $(patsubst %,$(OBJDIR)/$(C $(LIBDIR)/$(CALCDIR)/libcalc_%.so.1: $(OBJDIR)/$(CALCDIR)/calc_%.o if [ ! -d $(LIBDIR) ] ; then mkdir $(LIBDIR) ; fi if [ ! -d $(LIBDIR)/$(CALCDIR) ] ; then mkdir $(LIBDIR)/$(CALCDIR) ; fi - $(CC) $(LDFLAGS) -shared -Wl,-soname,libcalc_$*.so.1 -o $@ $< + $(CC) -shared -Wl,-soname,libcalc_$*.so.1 -o $@ $< cd $(@D) ; ln -sf libcalc_$*.so.1 libcalc_$*.so # Compile lib specific source files @@ -102,10 +113,10 @@ $(OBJDIR)/$(COMMDIR)/%.o: $(SRCDIR)/$(COMMDIR)/$$(*F).c $(INCDIR)/$$(*D)_comm.h if [ ! -d $(OBJDIR)/$(COMMDIR) ] ; then mkdir $(OBJDIR)/$(COMMDIR) ; fi if [ ! -d $(OBJDIR)/$(COMMDIR)/$(*D) ] ; then mkdir $(OBJDIR)/$(COMMDIR)/$(*D) ; fi cd $(INCDIR) ; ln -sfT $(*D)_comm.h specific_comm.h - $(CC) $(CFLAGS) -I$(INCDIR) -I$(LOCALDIR)/$(PAPIHIGHLEVELINCDIR) $< -o $@ + $(CC) $(CFLAGS) -I$(INCDIR) $< -o $@ $(OBJDIR)/%.o: $(SRCDIR)/$$(*F).c $(INCDIR)/$$(*D)_comm.h $(INCDIR)/commtech.h if [ ! -d $(OBJDIR) ] ; then mkdir $(OBJDIR) ; fi if [ ! -d $(OBJDIR)/$(*D) ] ; then mkdir $(OBJDIR)/$(*D) ; fi cd $(INCDIR) ; ln -sfT $(*D)_comm.h specific_comm.h - $(CC) $(CFLAGS) -I$(INCDIR) -I$(LOCALDIR)/$(PAPIHIGHLEVELINCDIR) $< -o $@ + $(CC) $(CFLAGS) -I$(INCDIR) -I$(LOCALDIR)/$(PHL_INCDIR) -I../$(PHLDIR)/$(PHL_INCDIR) $< -o $@ From d64645109101aadadc2cfc8b9a6e269dccb2b0f6 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Thu, 25 Jun 2009 17:29:44 +0200 Subject: [PATCH 37/62] commtechs: We can launch without LD_LIBRARY_PATH --- communication_techniques/lancement.sh | 71 ++++++++++++++++----------- 1 file changed, 43 insertions(+), 28 deletions(-) diff --git a/communication_techniques/lancement.sh b/communication_techniques/lancement.sh index 3263a8a..70e8f26 100755 --- a/communication_techniques/lancement.sh +++ b/communication_techniques/lancement.sh @@ -1,10 +1,13 @@ #! /bin/bash -set -u - # Files and directories binDir="bin" calcDir="calculation" +PHLDir="../papihighlevel" +PHLLibDir="lib" +PAPIDir="${PHLDir}/papi" +PAPILibDir="src" +PAPIPFMDir="libpfm-3.y/lib" # Param binList="asm_cache_comm c_cache_comm pipe_comm shared_mem_comm shared_mem_opt_comm jikes_barrier_comm fake_comm" # Type de communication @@ -21,38 +24,50 @@ logFileName="\$perfDirName/cache_\$typeCache-nbProd_\$nbProd-typeProd_\$typeProd expDirName="logs" perfDirName="$expDirName/perfCommMulti-`date +'%F-%Hh%Mm%S'`" -if [ -n $LD_LIBRARY_PATH ] +if [ -n "${LD_LIBRARY_PATH}" ] then - LD_LIBRARY_PATH_LEFT="${LD_LIBRARY_PATH}" - while [ -n "${LD_LIBRARY_PATH_LEFT}" ] - do - aLibDir="${LD_LIBRARY_PATH_LEFT%%:*}" - if [ -x ${aLibDir}/libpapi.so ] - then - papiLibPresent="1"; - fi - if [ -x ${aLibDir}/libpapihighlevel.so ] - then - papiHighLevelLibPresent="1"; - fi - if [ -n "${papiLibPresent}" -a -n "${papiHighLevelLibPresent}" ] - then - break - fi - LD_LIBRARY_PATH_LEFT="${LD_LIBRARY_PATH#*:}" - done - if [ -z "${papiLibPresent}" -o -z "${papiHighLevelLibPresent}" ] - then - echo "Libraries needed for this bench not accessible by \$LD_LIBRARY_PATH" > /dev/stderr # Is there a better way to display something on stderr ? - exit 1 - fi + LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${PHLDir}/${PHLLibDir}:${PAPIDir}/${PAPILibDir}:${PAPIDir}/${PAPILibDir}/${PAPIPFMDir}" else + LD_LIBRARY_PATH="${PHLDir}/${PHLLibDir}:${PAPIDir}/${PAPILibDir}:${PAPIDir}/${PAPILibDir}/${PAPIPFMDir}" +fi + +set -u + +PAPILibPresent="" +PFMLibPresent="" +papiHighLevelLibPresent="" +LD_LIBRARY_PATH_LEFT="${LD_LIBRARY_PATH}:" +while [ -n "${LD_LIBRARY_PATH_LEFT}" ] +do + aLibDir="${LD_LIBRARY_PATH_LEFT%%:*}" + if [ -x ${aLibDir}/libpapi.so.3 ] + then + PAPILibPresent="1"; + fi + if [ -x ${aLibDir}/libpfm.so.3 ] + then + PHLLibPresent="1"; + fi + if [ -x ${aLibDir}/libpapihighlevel.so ] + then + PHLLibPresent="1"; + fi + if [ -n "${PAPILibPresent}" -a -n "${PHLLibPresent}" -a -n "${PFMLibPresent}" ] + then + break + fi + LD_LIBRARY_PATH_LEFT="${LD_LIBRARY_PATH_LEFT#*:}" +done +if [ -z "${PAPILibPresent}" -o -z "${PHLLibPresent}" ] +then echo "Libraries needed for this bench not accessible by \$LD_LIBRARY_PATH" > /dev/stderr # Is there a better way to display something on stderr ? exit 1 fi -unset papiLibPresent -unset papiHighLevelLibPresent + +unset PAPILibPresent +unset PHLLibPresent unset LD_LIBRARY_PATH_LEFT +export LD_LIBRARY_PATH [ -d "$expDirName" ] || mkdir "$expDirName" [ -d "$perfDirName" ] || mkdir "$perfDirName" From 33614392cda9851ae50a30d19130619a7970473b Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Thu, 25 Jun 2009 17:40:42 +0200 Subject: [PATCH 38/62] No need to move the set -u --- communication_techniques/lancement.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/communication_techniques/lancement.sh b/communication_techniques/lancement.sh index 70e8f26..a17f094 100755 --- a/communication_techniques/lancement.sh +++ b/communication_techniques/lancement.sh @@ -1,5 +1,7 @@ #! /bin/bash +set -u + # Files and directories binDir="bin" calcDir="calculation" @@ -24,15 +26,13 @@ logFileName="\$perfDirName/cache_\$typeCache-nbProd_\$nbProd-typeProd_\$typeProd expDirName="logs" perfDirName="$expDirName/perfCommMulti-`date +'%F-%Hh%Mm%S'`" -if [ -n "${LD_LIBRARY_PATH}" ] +if [ -n "${LD_LIBRARY_PATH:-}" ] # If LD_LIBRARY_PATH is unbound then the expansion is "null" value then LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${PHLDir}/${PHLLibDir}:${PAPIDir}/${PAPILibDir}:${PAPIDir}/${PAPILibDir}/${PAPIPFMDir}" else LD_LIBRARY_PATH="${PHLDir}/${PHLLibDir}:${PAPIDir}/${PAPILibDir}:${PAPIDir}/${PAPILibDir}/${PAPIPFMDir}" fi -set -u - PAPILibPresent="" PFMLibPresent="" papiHighLevelLibPresent="" From a9c71bf5d8c9b79494d0612fc76628d20aafa75d Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Thu, 25 Jun 2009 18:00:02 +0200 Subject: [PATCH 39/62] commtechs: Replace the test by a nicer shell trick --- communication_techniques/lancement.sh | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/communication_techniques/lancement.sh b/communication_techniques/lancement.sh index a17f094..1b6bb87 100755 --- a/communication_techniques/lancement.sh +++ b/communication_techniques/lancement.sh @@ -26,12 +26,7 @@ logFileName="\$perfDirName/cache_\$typeCache-nbProd_\$nbProd-typeProd_\$typeProd expDirName="logs" perfDirName="$expDirName/perfCommMulti-`date +'%F-%Hh%Mm%S'`" -if [ -n "${LD_LIBRARY_PATH:-}" ] # If LD_LIBRARY_PATH is unbound then the expansion is "null" value -then - LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${PHLDir}/${PHLLibDir}:${PAPIDir}/${PAPILibDir}:${PAPIDir}/${PAPILibDir}/${PAPIPFMDir}" -else - LD_LIBRARY_PATH="${PHLDir}/${PHLLibDir}:${PAPIDir}/${PAPILibDir}:${PAPIDir}/${PAPILibDir}/${PAPIPFMDir}" -fi +LD_LIBRARY_PATH="${LD_LIBRARY_PATH:-}${LD_LIBRARY_PATH:+:}${PHLDir}/${PHLLibDir}:${PAPIDir}/${PAPILibDir}:${PAPIDir}/${PAPILibDir}/${PAPIPFMDir}" PAPILibPresent="" PFMLibPresent="" From 7bfc46db78857d0f68e19c909c17038f5f59cfa3 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Tue, 30 Jun 2009 22:32:59 +0200 Subject: [PATCH 40/62] commtech: Delete pages free Pages cannots be freed as fast as they are allocated, so this whole mecanism can only delay the kernel panic. It's wiser to exit badly if too much memory is consumed --- .../src/communication/jikes_barrier.c | 33 ++----------------- 1 file changed, 3 insertions(+), 30 deletions(-) diff --git a/communication_techniques/src/communication/jikes_barrier.c b/communication_techniques/src/communication/jikes_barrier.c index 4c0c45a..e4f9942 100644 --- a/communication_techniques/src/communication/jikes_barrier.c +++ b/communication_techniques/src/communication/jikes_barrier.c @@ -30,7 +30,6 @@ static __thread void **local_tail = NULL; static __thread void **local_tail_buffer_end = NULL; static struct double_linked_list *global_tail = NULL; static struct double_linked_list *global_head = NULL; -static int collect = 0; static int bufsenqueued = 0; static unsigned int lock = 0; @@ -150,31 +149,10 @@ void closeAndEnqueueTail(int arity) void checkForAsyncCollection(void) { - if (bufsenqueued >= 102400) /* We use more than 100 Mo */ - collect = 1; -} - -void free_pages(struct double_linked_list *list_cur) -{ - if (list_cur == NULL) - return; - spin_lock(&lock); - /* - * We may free some buffer allocated after this line is executed, thus - * the real number of buffer enqueued could be bigger. - * This is done to avoid to keep the lock during the while loop and for - * checkForAsyncCollection to first start asking for a collection at - * 100 Mo in the *worst* case - */ - bufsenqueued = 0; - spin_unlock(&lock); - while (global_head != list_cur) /* We know closeAndEnqueueTail() ask enqueue() to enqueue at tail */ + if (bufsenqueued >= 262144) /* We use more than 1 Go */ { - void *buf_start; - - buf_start = (void *) ((uintptr_t) global_head & BUFFER_MASK); - global_head = global_head->next; - free(buf_start); + fprintf(stderr, "We use 1.5 Go. Program terminated before kernel panic\n"); + exit(1); } } @@ -215,11 +193,6 @@ void reception(void (*on_receive)(void *)) buf_start = (void **) (((uintptr_t) &list_cur->prev) & ~BUFFER_MASK); for (buf_ptr = buf_start; buf_ptr != (void **) &list_cur->prev; buf_ptr++) on_receive(*buf_ptr); - if (collect) - { - free_pages(list_cur); - collect = 0; - } while (cont && (list_cur->next == NULL)); } while (cont); } From c98db4b4baaa7599b0c1e21b90fed2816f798f39 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Tue, 30 Jun 2009 22:35:11 +0200 Subject: [PATCH 41/62] commtech: do_calc() return a void ** This respect what we claim to send to the send() function and allow to reduce the FAKE_NURSERY_START. Thus we are sure gcc won't optimize the second part of the if in include/jikes_barrier_comm.h --- .../src/calculation/calc_mat.c | 6 ++++-- communication_techniques/src/main.c | 14 +++++++------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/communication_techniques/src/calculation/calc_mat.c b/communication_techniques/src/calculation/calc_mat.c index f3044de..c7f2bd2 100644 --- a/communication_techniques/src/calculation/calc_mat.c +++ b/communication_techniques/src/calculation/calc_mat.c @@ -9,6 +9,7 @@ static int *mat, *vect; static int li; static int n, m; /* Size of the matrice: n lines, m columns */ +static int *mat_cell_ptr; int init_calc(int size) { @@ -36,7 +37,7 @@ int init_calc(int size) return 0; } -void *do_calc(void) +void **do_calc(void) { int co, p = 0; @@ -45,7 +46,8 @@ void *do_calc(void) mat[li * m] = p; if (unlikely(++li >= n)) li = 0; - return &mat[li * m]; + mat_cell_ptr = &mat[li * m]; + return (void **) &mat_cell_ptr; } int end_calc(void) diff --git a/communication_techniques/src/main.c b/communication_techniques/src/main.c index 7a7bc8e..ce61bdd 100644 --- a/communication_techniques/src/main.c +++ b/communication_techniques/src/main.c @@ -30,7 +30,7 @@ static long nb_bufs_sent = 0; long nb_prod = 0; static int (*init_calc)(int) = NULL; -static void *(*do_calc)(void) = NULL; +static void **(*do_calc)(void) = NULL; static int (*end_calc)(void) = NULL; static int shared = 0; pthread_cond_t cond_cons_has_finished = PTHREAD_COND_INITIALIZER; @@ -60,11 +60,11 @@ int do_noinit(int unused) return 0; } -void *do_nocalc(void) +void **do_nocalc(void) { - static int an_int; + static int an_int, *an_int_ptr = &an_int; - return &an_int; + return (void **) &an_int_ptr; } int do_noend(void) @@ -97,9 +97,9 @@ int analyse_options(int argc, char *argv[]) fprintf(stderr, "dlopen error: %s\n", dlerror()); return -1; } - init_calc = dlsym(dl_descriptor, "init_calc"); - do_calc = dlsym(dl_descriptor, "do_calc"); - end_calc = dlsym(dl_descriptor, "end_calc"); + init_calc = (int (*)(int)) dlsym(dl_descriptor, "init_calc"); + do_calc = (void ** (*)(void)) dlsym(dl_descriptor, "do_calc"); + end_calc = (int (*)(void)) dlsym(dl_descriptor, "end_calc"); if ((init_calc == NULL) || (do_calc == NULL) || (end_calc == NULL)) { fprintf(stderr, "A symbol cannot be loaded: %s\n", dlerror()); From e04818645a5fb69485758aa9308fe0c19363e67f Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Tue, 30 Jun 2009 22:37:55 +0200 Subject: [PATCH 42/62] commtech: Add a new calculation method This calculation performs only a loop and avoid cache pollution --- communication_techniques/Makefile | 2 +- .../src/calculation/calc_useless_loop.c | 27 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 communication_techniques/src/calculation/calc_useless_loop.c diff --git a/communication_techniques/Makefile b/communication_techniques/Makefile index acdb948..d14a4b1 100644 --- a/communication_techniques/Makefile +++ b/communication_techniques/Makefile @@ -33,7 +33,7 @@ CC=gcc # Files BINNAMES:=asm_cache_comm c_cache_comm pipe_comm shared_mem_comm shared_mem_opt_comm jikes_barrier_comm fake_comm -CALCLIBSNAMES:=calc_mat +CALCLIBSNAMES:=calc_mat calc_useless_loop BINS:=$(patsubst %,$(BINDIR)/%,$(BINNAMES)) CALCLIBS:=$(patsubst %,$(LIBDIR)/$(CALCDIR)/lib%.so.1,$(CALCLIBSNAMES)) MAIN_OBJS:=main.o diff --git a/communication_techniques/src/calculation/calc_useless_loop.c b/communication_techniques/src/calculation/calc_useless_loop.c new file mode 100644 index 0000000..adbf4ee --- /dev/null +++ b/communication_techniques/src/calculation/calc_useless_loop.c @@ -0,0 +1,27 @@ +#include +#include +#include + + +static int nb_loop = 0, prod = 0, *prod_ptr = ∏ + +int init_calc(int param_nb_loop) +{ + nb_loop = param_nb_loop; + srand((unsigned int) time(NULL)); + return 0; +} + +void **do_calc(void) +{ + int i; + + for(i = 0; i < nb_loop; i++) + prod += rand(); + return (void **) &prod_ptr; +} + +int end_calc(void) +{ + return 0; +} From ba13c18af706a2172522f4e183c305c42e1152ad Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Wed, 1 Jul 2009 00:45:19 +0200 Subject: [PATCH 43/62] commtech: Free pages when jikes barrier ends --- .../src/communication/jikes_barrier.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/communication_techniques/src/communication/jikes_barrier.c b/communication_techniques/src/communication/jikes_barrier.c index e4f9942..d148bdf 100644 --- a/communication_techniques/src/communication/jikes_barrier.c +++ b/communication_techniques/src/communication/jikes_barrier.c @@ -195,4 +195,12 @@ void reception(void (*on_receive)(void *)) on_receive(*buf_ptr); while (cont && (list_cur->next == NULL)); } while (cont); + while (global_head != NULL) + { + void *tmp; + + tmp = global_head; + global_head = global_head->next; + free(tmp); + } } From e90348b54ca21ef2043de280e37dfefc00804fac Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Wed, 1 Jul 2009 01:48:13 +0200 Subject: [PATCH 44/62] commtech: BUFFIX in freeing pages Don't try to free the middle of an allocation --- communication_techniques/src/communication/jikes_barrier.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/communication_techniques/src/communication/jikes_barrier.c b/communication_techniques/src/communication/jikes_barrier.c index d148bdf..6e0772f 100644 --- a/communication_techniques/src/communication/jikes_barrier.c +++ b/communication_techniques/src/communication/jikes_barrier.c @@ -199,7 +199,7 @@ void reception(void (*on_receive)(void *)) { void *tmp; - tmp = global_head; + tmp = (void *) ((uintptr_t) global_head & ~BUFFER_MASK); global_head = global_head->next; free(tmp); } From 243d8810f1e2d2b0a28b9418da4a3ca035dbdfcd Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Wed, 1 Jul 2009 01:49:16 +0200 Subject: [PATCH 45/62] commtech: avoid a double free corruption Remove srand and rand function call as they generates double free corruption (???) --- .../src/calculation/calc_useless_loop.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/communication_techniques/src/calculation/calc_useless_loop.c b/communication_techniques/src/calculation/calc_useless_loop.c index adbf4ee..a10257a 100644 --- a/communication_techniques/src/calculation/calc_useless_loop.c +++ b/communication_techniques/src/calculation/calc_useless_loop.c @@ -1,14 +1,14 @@ #include -#include #include +#include static int nb_loop = 0, prod = 0, *prod_ptr = ∏ +unsigned int seedp; int init_calc(int param_nb_loop) { nb_loop = param_nb_loop; - srand((unsigned int) time(NULL)); return 0; } @@ -17,7 +17,7 @@ void **do_calc(void) int i; for(i = 0; i < nb_loop; i++) - prod += rand(); + prod += 42; return (void **) &prod_ptr; } From 7a1610961c0ff5bd31a56e80209f57bc0a83c9d3 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Wed, 1 Jul 2009 02:34:50 +0200 Subject: [PATCH 46/62] commtech: BUGFIX unwanted optimization Replace prod += 42 by prod += fourty_two where fourty_two is a volatile variable to avoid replacement of the loop into a prod += 42 * nb_loop --- communication_techniques/src/calculation/calc_useless_loop.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/communication_techniques/src/calculation/calc_useless_loop.c b/communication_techniques/src/calculation/calc_useless_loop.c index a10257a..84865e8 100644 --- a/communication_techniques/src/calculation/calc_useless_loop.c +++ b/communication_techniques/src/calculation/calc_useless_loop.c @@ -4,6 +4,7 @@ static int nb_loop = 0, prod = 0, *prod_ptr = ∏ +volatile int fourty_two = 42; unsigned int seedp; int init_calc(int param_nb_loop) @@ -17,7 +18,7 @@ void **do_calc(void) int i; for(i = 0; i < nb_loop; i++) - prod += 42; + prod += fourty_two; return (void **) &prod_ptr; } From 3341546c753a19b0732b7e82c40f830bfe8c10be Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Wed, 1 Jul 2009 02:36:11 +0200 Subject: [PATCH 47/62] commtech: calc lib take 1 argument on command line --- communication_techniques/lancement.sh | 22 ++++++++++++++++++---- communication_techniques/src/main.c | 25 +++++++++++++++++++++++-- 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/communication_techniques/lancement.sh b/communication_techniques/lancement.sh index 1b6bb87..c242329 100755 --- a/communication_techniques/lancement.sh +++ b/communication_techniques/lancement.sh @@ -14,7 +14,7 @@ PAPIPFMDir="libpfm-3.y/lib" # Param binList="asm_cache_comm c_cache_comm pipe_comm shared_mem_comm shared_mem_opt_comm jikes_barrier_comm fake_comm" # Type de communication nbProdList="1" # Nombre de cores producteurs -typeProdList="none matrice" # Methode pour produire les valeurs +typeProdList="none matrice useless_loop" # Methode pour produire les valeurs typeCacheList="L2 mem" # Niveau de cache partage # Const @@ -22,7 +22,7 @@ nbIter="5000000" # Nb de lignes produites sizeBuf="1" # En nombre de lignes de cache # Nom generique des fichiers de log -logFileName="\$perfDirName/cache_\$typeCache-nbProd_\$nbProd-typeProd_\$typeProd-nbIter_\$nbIter-\$bin.log" +logFileName="\$perfDirName/cache_\$typeCache-nbProd_\$nbProd-typeProd_\$typeProd-argTypeProd_\$argTypeProd-nbIter_\$nbIter-\$bin.log" expDirName="logs" perfDirName="$expDirName/perfCommMulti-`date +'%F-%Hh%Mm%S'`" @@ -70,7 +70,8 @@ export LD_LIBRARY_PATH function_run () { case $typeProd in "none" ) optTypeProd="" ;; - "matrice" ) optTypeProd="-c lib/${calcDir}/libcalc_mat.so" ;; + "matrice" ) optTypeProd="-c lib/${calcDir}/libcalc_mat.so 16" ;; + "useless_loop" ) optTypeProd="-c lib/${calcDir}/libcalc_useless_loop.so ${nb_useless_loop}" ;; * ) exit 1 ;; esac case $typeCache in @@ -104,7 +105,20 @@ for nbProd in $nbProdList ; do for typeProd in $typeProdList; do for typeCache in $typeCacheList ; do for bin in $binList ; do - function_run + if [ "$typeProd" = "useless_loop" ] + then + case $bin in + "jikes_barrier_comm" | "asm_cache_comm" | "c_cache_comm" ) + for argTypeProd in `seq 1 50 5` ; do + function_run ; + done ;; + * ) argTypeProd=1 ; + function_run ;; + esac + else + argTypeProd=1 ; + function_run ; + fi done done done diff --git a/communication_techniques/src/main.c b/communication_techniques/src/main.c index ce61bdd..f8aa110 100644 --- a/communication_techniques/src/main.c +++ b/communication_techniques/src/main.c @@ -20,7 +20,6 @@ #define toString(x) doStringification(x) #define doStringification(x) #x -#define INIT_CALC_ARG 16 #define WORDS_PER_BUF (BUF_SIZE / sizeof(uintptr_t)) #define DIV_SEC(secs, div) ((unsigned ) (((unsigned) secs) / (unsigned long) (div))) #define DIV_USEC(nsecs, nusecs, div) ((unsigned) (((unsigned) (nusecs) + 1000000 * \ @@ -37,6 +36,7 @@ pthread_cond_t cond_cons_has_finished = PTHREAD_COND_INITIALIZER; pthread_mutex_t mutex_cons_has_finished = PTHREAD_MUTEX_INITIALIZER; static int consumer_has_finished = 0; static int producers_ended = 0; +static int init_calc_arg = 0; void usage(char *argv[]) { @@ -105,6 +105,27 @@ int analyse_options(int argc, char *argv[]) fprintf(stderr, "A symbol cannot be loaded: %s\n", dlerror()); return -1; } + if ((optind == argc) || (*argv[optind] == '-')) + { + fprintf(stderr, "Missing argument for -c option\n"); + return -1; + } + { + char *inval; + init_calc_arg = strtol(argv[optind], &inval, 10); + if ((*argv[optind] == '\0') || (*inval != '\0')) + { + fprintf(stderr, "Option '-c' needs also an integer argument\n"); + return -1; + } + if ((init_calc_arg <= 0) || ((init_calc_arg == LONG_MAX) && errno == ERANGE)) + { + fprintf(stderr, "Number of useless loop to be done between 2 send must be" + " between 1 and %ld, both inclusive\n", LONG_MAX); + return -1; + } + } + optind++; } break; case 'h' : @@ -232,7 +253,7 @@ void *producer(void *unused) return &nb_prod; /* &nb_prod can't be NULL, whatever NULL is bound to */ } } - if (init_calc(INIT_CALC_ARG)) + if (init_calc(init_calc_arg)) { fprintf(stderr, "Initialization of calculation has failed\n"); wait_consumer(); From 7a5535cc430551a195283e5ef1951e3b579dd754 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Wed, 1 Jul 2009 02:41:56 +0200 Subject: [PATCH 48/62] commtech: Be ready to compile totally locally --- papihighlevel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/papihighlevel b/papihighlevel index 2bb75f2..16449c5 160000 --- a/papihighlevel +++ b/papihighlevel @@ -1 +1 @@ -Subproject commit 2bb75f2be7e6b7f6de224b3ec0d144ec1805229f +Subproject commit 16449c571f7363d0a6dc8293df8f0aaec40b492a From 415004fb4b1af7ccb0e8b36b5f510b72ba5ce8e4 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Wed, 1 Jul 2009 02:45:28 +0200 Subject: [PATCH 49/62] commtech: Update usage help --- communication_techniques/src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/communication_techniques/src/main.c b/communication_techniques/src/main.c index f8aa110..ed3cfe8 100644 --- a/communication_techniques/src/main.c +++ b/communication_techniques/src/main.c @@ -48,7 +48,7 @@ void usage(char *argv[]) "Facultative options :\n" "-h\t\t\tPrint this help\n" "-s\t\t\tShare the same L2 cache or not\n" - "-c calculation_libname\tLibrary to use for calculation\n" + "-c calculation_libname arg\tLibrary to use for calculation with its argument\n" "\t\t\tThis library must implement functions in calc.h\n"; printf("Usage : %s %s\n", argv[0], format); printf("Options :\n"); From 698341b99edda8e76a2cedea22a4704cd68583b7 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Wed, 1 Jul 2009 03:10:38 +0200 Subject: [PATCH 50/62] commtech: Update usage help --- communication_techniques/src/main.c | 44 ++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/communication_techniques/src/main.c b/communication_techniques/src/main.c index ed3cfe8..f080331 100644 --- a/communication_techniques/src/main.c +++ b/communication_techniques/src/main.c @@ -31,7 +31,7 @@ long nb_prod = 0; static int (*init_calc)(int) = NULL; static void **(*do_calc)(void) = NULL; static int (*end_calc)(void) = NULL; -static int shared = 0; +static int shared = 0; /* We are not shared by default */ pthread_cond_t cond_cons_has_finished = PTHREAD_COND_INITIALIZER; pthread_mutex_t mutex_cons_has_finished = PTHREAD_MUTEX_INITIALIZER; static int consumer_has_finished = 0; @@ -42,14 +42,18 @@ void usage(char *argv[]) { char format[] = "-n [options]"; char options[] = "Required options :\n" - "-n nb_buffer_sent\tNumber of buffer to send to another core\n" - "\t\t\tBuffer size is " toString(BUF_SIZE) " bytes\n" - "-p nb_producers\tNumber of producers which send data to another core\n" + "-n nb_buffer_sent\t\tNumber of buffer to send to another core\n" + "\t\t\t\tBuffer size is " toString(BUF_SIZE) " bytes\n" + "-p nb_producers\t\t\tNumber of producers which send data to another core\n" "Facultative options :\n" - "-h\t\t\tPrint this help\n" - "-s\t\t\tShare the same L2 cache or not\n" + "-h\t\t\t\tPrint this help\n" + "-s \t\t\tShare the same L cache or not\n" + "\t\t\t\tIf level is:\n" + "\t\t\t\t\t> 0, then the same L must be shared\n" + "\t\t\t\t\t< 0, then different L must be used\n" + "\t\t\t\t\t= 0, then no constraint is given, only main memory (RAM) is guaranteed to be shared\n" "-c calculation_libname arg\tLibrary to use for calculation with its argument\n" - "\t\t\tThis library must implement functions in calc.h\n"; + "\t\t\t\tThis library must implement functions in calc.h\n"; printf("Usage : %s %s\n", argv[0], format); printf("Options :\n"); printf("%s\n", options); @@ -77,7 +81,7 @@ int analyse_options(int argc, char *argv[]) int opt; opterr = 0; - while ((opt = getopt(argc, argv, ":hsc:n:p:")) != -1) + while ((opt = getopt(argc, argv, ":hs::c:n:p:")) != -1) { switch (opt) { @@ -164,8 +168,28 @@ int analyse_options(int argc, char *argv[]) } break; case 's' : - shared = 1; - /* TODO: shared Ln cache */ + if ((optind != argc) && (*argv[optind] != '-')) + { + int share_level; + char *inval; + share_level = strtol(argv[optind], &inval, 10); + if ((*argv[optind] == '\0') || (*inval != '\0')) + { + fprintf(stderr, "Option '-p' needs an integer argument\n"); + return -1; + } + if ((share_level == LONG_MIN) || ((share_level == LONG_MAX) && errno == ERANGE)) + { + fprintf(stderr, "Shared memory level must be between %ld and %ld, both inclusive\n", LONG_MIN, LONG_MAX); + return -1; + } + /* TODO: Real management of shared memory level */ + if (share_level <= 0) /* -x: We wan't level x not to be shared; 0 do as we want, only memory is guaranteed to be shared */ + shared = 0; + else + shared = 1; + optind++; + } break; case '?' : fprintf(stderr, "Option inconnue\n"); From 3c00b5727ef8f10dc092315935aeb901c5ba445b Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Wed, 1 Jul 2009 16:25:36 +0200 Subject: [PATCH 51/62] commtech: calc_mat takes 16 as argument --- communication_techniques/lancement.sh | 32 +++++++++++++++------------ 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/communication_techniques/lancement.sh b/communication_techniques/lancement.sh index c242329..52b5b93 100755 --- a/communication_techniques/lancement.sh +++ b/communication_techniques/lancement.sh @@ -105,20 +105,24 @@ for nbProd in $nbProdList ; do for typeProd in $typeProdList; do for typeCache in $typeCacheList ; do for bin in $binList ; do - if [ "$typeProd" = "useless_loop" ] - then - case $bin in - "jikes_barrier_comm" | "asm_cache_comm" | "c_cache_comm" ) - for argTypeProd in `seq 1 50 5` ; do - function_run ; - done ;; - * ) argTypeProd=1 ; - function_run ;; - esac - else - argTypeProd=1 ; - function_run ; - fi + case $typeProd in + "useless_loop" ) + case $bin in + "jikes_barrier_comm" | "asm_cache_comm" | "c_cache_comm" ) + for argTypeProd in `seq 1 50 5` ; do + function_run ; + done ;; + * ) + argTypeProd=1 ; + function_run ;; + esac ;; + "matrice" ) + argTypeProd=16 ; + function_run ;; + * ) + argTypeProd=1 ; + function_run ;; + esac done done done From 06e1331dbbf7b1140a16f0e1b018d73edc3c5ae9 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Mon, 6 Jul 2009 17:12:57 +0200 Subject: [PATCH 52/62] commtechs BUGFIX: wrong varname (nb_useless_loop) nb_useless_loop has been renamed in argTypeProd but one usage of nb_useless_loop has remained in lancement.sh --- communication_techniques/lancement.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/communication_techniques/lancement.sh b/communication_techniques/lancement.sh index 52b5b93..d3b64de 100755 --- a/communication_techniques/lancement.sh +++ b/communication_techniques/lancement.sh @@ -71,7 +71,7 @@ function_run () { case $typeProd in "none" ) optTypeProd="" ;; "matrice" ) optTypeProd="-c lib/${calcDir}/libcalc_mat.so 16" ;; - "useless_loop" ) optTypeProd="-c lib/${calcDir}/libcalc_useless_loop.so ${nb_useless_loop}" ;; + "useless_loop" ) optTypeProd="-c lib/${calcDir}/libcalc_useless_loop.so ${argTypeProd}" ;; * ) exit 1 ;; esac case $typeCache in From 60214d62f08238916e642d9084bb5ebac669c5a3 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Tue, 7 Jul 2009 14:32:22 +0200 Subject: [PATCH 53/62] commtechs: BUGFIX in seq usage --- communication_techniques/lancement.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/communication_techniques/lancement.sh b/communication_techniques/lancement.sh index d3b64de..e85f46d 100755 --- a/communication_techniques/lancement.sh +++ b/communication_techniques/lancement.sh @@ -109,7 +109,7 @@ for nbProd in $nbProdList ; do "useless_loop" ) case $bin in "jikes_barrier_comm" | "asm_cache_comm" | "c_cache_comm" ) - for argTypeProd in `seq 1 50 5` ; do + for argTypeProd in 1 `seq 5 5 50` ; do function_run ; done ;; * ) From c99d8be1009618668531919691cad51ae02a46ba Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Tue, 7 Jul 2009 15:56:20 +0200 Subject: [PATCH 54/62] commtechs: BUGFIX deadlock in thread init --- communication_techniques/src/communication/common.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/communication_techniques/src/communication/common.c b/communication_techniques/src/communication/common.c index 900f027..76193b4 100644 --- a/communication_techniques/src/communication/common.c +++ b/communication_techniques/src/communication/common.c @@ -52,8 +52,10 @@ int init_producer_thread(void) thread_num = get_thread_number(); if (init_thread_comm(&tcomms[thread_num])) { + pthread_mutex_lock(&init_lock); error = 1; pthread_cond_signal(&init_cond); + pthread_mutex_unlock(&init_lock); return -1; } pthread_mutex_lock(&init_lock); From 97fb64709f0c343e47072a182a157c13801deb2a Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Tue, 7 Jul 2009 16:00:51 +0200 Subject: [PATCH 55/62] commtech: Add a TODO list --- communication_techniques/TODO | 1 + 1 file changed, 1 insertion(+) create mode 100644 communication_techniques/TODO diff --git a/communication_techniques/TODO b/communication_techniques/TODO new file mode 100644 index 0000000..48d5d19 --- /dev/null +++ b/communication_techniques/TODO @@ -0,0 +1 @@ +- move init_thread_library in papihighlevel.c in init_library (the constructor is only called once) From 5e3a7f6ce0ee582e43e99793d2c768ab41ab2e7e Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Tue, 7 Jul 2009 16:08:00 +0200 Subject: [PATCH 56/62] commtechs: BUGFIX wait threads to be initialized --- communication_techniques/src/communication/common.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/communication_techniques/src/communication/common.c b/communication_techniques/src/communication/common.c index 76193b4..03f02dd 100644 --- a/communication_techniques/src/communication/common.c +++ b/communication_techniques/src/communication/common.c @@ -58,10 +58,13 @@ int init_producer_thread(void) pthread_mutex_unlock(&init_lock); return -1; } - pthread_mutex_lock(&init_lock); - init = 1; - pthread_cond_signal(&init_cond); - pthread_mutex_unlock(&init_lock); + if (thread_num == nb_prod - 1) + { + pthread_mutex_lock(&init_lock); + init = 1; + pthread_cond_signal(&init_cond); + pthread_mutex_unlock(&init_lock); + } return 0; } From d38f9150b2f0fb43e6b6b8a0b7b041e75ee1ded1 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Wed, 8 Jul 2009 18:33:32 +0200 Subject: [PATCH 57/62] commtechs: Make legend looks nicer s/mem/Memory/ --- communication_techniques/lancement.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/communication_techniques/lancement.sh b/communication_techniques/lancement.sh index e85f46d..5954686 100755 --- a/communication_techniques/lancement.sh +++ b/communication_techniques/lancement.sh @@ -15,7 +15,7 @@ PAPIPFMDir="libpfm-3.y/lib" binList="asm_cache_comm c_cache_comm pipe_comm shared_mem_comm shared_mem_opt_comm jikes_barrier_comm fake_comm" # Type de communication nbProdList="1" # Nombre de cores producteurs typeProdList="none matrice useless_loop" # Methode pour produire les valeurs -typeCacheList="L2 mem" # Niveau de cache partage +typeCacheList="L2 Memory" # Niveau de cache partage # Const nbIter="5000000" # Nb de lignes produites @@ -75,7 +75,7 @@ function_run () { * ) exit 1 ;; esac case $typeCache in - "mem" ) optTypeCache="" ;; + "Memory" ) optTypeCache="" ;; "L2" ) optTypeCache="-s" ;; * ) exit 1 ;; esac From 19ef1d98f2eccd15fc6766b232053701b22eeea6 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Wed, 8 Jul 2009 18:42:51 +0200 Subject: [PATCH 58/62] commtechs: Add bench_ before bench name --- communication_techniques/parsing.sh | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/communication_techniques/parsing.sh b/communication_techniques/parsing.sh index 87c697c..560597e 100755 --- a/communication_techniques/parsing.sh +++ b/communication_techniques/parsing.sh @@ -22,24 +22,24 @@ echo "set terminal postscript landscape color" >> multicores.gnuplot for prod in $prodList ; do for bench in "communication" "barriere" ; do for metrique in $metriqueList ; do - > $bench-prod_$prod-$metrique.dat + > bench_$bench-prod_$prod-$metrique.dat done for com in `eval echo \\\$\${bench}List` ; do for metrique in $metriqueList ; do - echo -ne "\n$com\t\t" >> $bench-prod_$prod-$metrique.dat + echo -ne "\n$com\t\t" >> bench_$bench-prod_$prod-$metrique.dat done for cache in $cacheList ; do for value in `perl -n -e 'print "$1 $2 $3" if /cache hits.* (\d+) \/ (\S+) \/ (\S+)/' cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do - echo -ne "\t$value " >> $bench-prod_$prod-cache_hits.dat + echo -ne "\t$value " >> bench_$bench-prod_$prod-cache_hits.dat done for value in `perl -n -e 'print "$1 $2 $3" if /cache miss.* (\d+) \/ (\S+) \/ (\S+)/' cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do - echo -ne "\t$value" >> $bench-prod_$prod-cache_miss.dat + echo -ne "\t$value" >> bench_$bench-prod_$prod-cache_miss.dat done for value in `perl -n -e 'print "$1 $2 $3" if /cycles.* (\d+) \/ (\S+) \/ (\S+)/' cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do - echo -ne "\t$value" >> $bench-prod_$prod-cycles.dat + echo -ne "\t$value" >> bench_$bench-prod_$prod-cycles.dat done for value in `perl -n -e 'print "$1 $2 $3" if /total_time.* (\S+) \/ (\S+) \/ (\S+)/' cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do - echo -ne "\t$value" >> $bench-prod_$prod-total_time.dat + echo -ne "\t$value" >> bench_$bench-prod_$prod-total_time.dat done done @@ -59,14 +59,14 @@ for prod in $prodList ; do || echo "set yrange [*:*]" >> multicores.gnuplot echo "set title \"Producteur : $prod\"" >> multicores.gnuplot echo "set ylabel \"$ylabel\"" >> multicores.gnuplot - echo "set output '$bench-prod_$prod-$metrique-total-$yscale.ps'" >> multicores.gnuplot - echo "plot '$bench-prod_$prod-$metrique.dat' using 2:xtic(1) ti 'L2', '' u 5 ti 'MEM'" >> multicores.gnuplot + echo "set output 'bench_$bench-prod_$prod-$metrique-total-$yscale.ps'" >> multicores.gnuplot + echo "plot 'bench_$bench-prod_$prod-$metrique.dat' using 2:xtic(1) ti 'L2', '' u 5 ti 'MEM'" >> multicores.gnuplot echo "set ylabel \"$ylabel par boucle\"" >> multicores.gnuplot - echo "set output '$bench-prod_$prod-$metrique-byLoop-$yscale.ps'" >> multicores.gnuplot - echo "plot '$bench-prod_$prod-$metrique.dat' using 3:xtic(1) ti 'L2', '' u 6 ti 'MEM'" >> multicores.gnuplot + echo "set output 'bench_$bench-prod_$prod-$metrique-byLoop-$yscale.ps'" >> multicores.gnuplot + echo "plot 'bench_$bench-prod_$prod-$metrique.dat' using 3:xtic(1) ti 'L2', '' u 6 ti 'MEM'" >> multicores.gnuplot echo "set ylabel \"$ylabel par ecriture\"" >> multicores.gnuplot - echo "set output '$bench-prod_$prod-$metrique-byWrite-$yscale.ps'" >> multicores.gnuplot - echo "plot '$bench-prod_$prod-$metrique.dat' using 4:xtic(1) ti 'L2', '' u 7 ti 'MEM'" >> multicores.gnuplot + echo "set output 'bench_$bench-prod_$prod-$metrique-byWrite-$yscale.ps'" >> multicores.gnuplot + echo "plot 'bench_$bench-prod_$prod-$metrique.dat' using 4:xtic(1) ti 'L2', '' u 7 ti 'MEM'" >> multicores.gnuplot done done done From 69417b1cfa90e543858181f180d10324e70a746f Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Wed, 8 Jul 2009 18:58:18 +0200 Subject: [PATCH 59/62] Intermediate parsing.sh (1) --- communication_techniques/parsing.sh | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/communication_techniques/parsing.sh b/communication_techniques/parsing.sh index 560597e..c764048 100755 --- a/communication_techniques/parsing.sh +++ b/communication_techniques/parsing.sh @@ -23,27 +23,37 @@ for prod in $prodList ; do for bench in "communication" "barriere" ; do for metrique in $metriqueList ; do > bench_$bench-prod_$prod-$metrique.dat + for file in cache_$cache-*-typeProd_$prod-*-${com}_comm.log ; do + argTypeProd=`echo "$file" | sed -r "s/.*argTypeProd_([[:digit:]]+).*/\1/"` + echo -ne "\t\t$argTypeProd" >> bench_$bench-prod_$prod-$metrique.dat + done done for com in `eval echo \\\$\${bench}List` ; do for metrique in $metriqueList ; do echo -ne "\n$com\t\t" >> bench_$bench-prod_$prod-$metrique.dat done for cache in $cacheList ; do - for value in `perl -n -e 'print "$1 $2 $3" if /cache hits.* (\d+) \/ (\S+) \/ (\S+)/' cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do + for value in `perl -n -e 'print "$1 $2 $3 " if /cache hits.* (\d+) \/ (\S+) \/ (\S+)/' cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do echo -ne "\t$value " >> bench_$bench-prod_$prod-cache_hits.dat done - for value in `perl -n -e 'print "$1 $2 $3" if /cache miss.* (\d+) \/ (\S+) \/ (\S+)/' cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do + for value in `perl -n -e 'print "$1 $2 $3 " if /cache miss.* (\d+) \/ (\S+) \/ (\S+)/' cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do echo -ne "\t$value" >> bench_$bench-prod_$prod-cache_miss.dat done - for value in `perl -n -e 'print "$1 $2 $3" if /cycles.* (\d+) \/ (\S+) \/ (\S+)/' cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do + for value in `perl -n -e 'print "$1 $2 $3 " if /cycles.* (\d+) \/ (\S+) \/ (\S+)/' cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do echo -ne "\t$value" >> bench_$bench-prod_$prod-cycles.dat done - for value in `perl -n -e 'print "$1 $2 $3" if /total_time.* (\S+) \/ (\S+) \/ (\S+)/' cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do + for value in `perl -n -e 'print "$1 $2 $3 " if /total_time.* (\S+) \/ (\S+) \/ (\S+)/' cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do echo -ne "\t$value" >> bench_$bench-prod_$prod-total_time.dat done done done + if [ "${bench}" = "barriere" ] ; + then + echo "set style data lines" >> multicores.gnuplot + else + echo "set style data histogram" >> multicores.gnuplot + fi for metrique in $metriqueList ; do case "$metrique" in cache_hits) ylabel="Nb cache hit" ;; From 31a2e59227ac7a2dcf5518ccc5dba99ea9999b27 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Tue, 28 Jul 2009 01:16:11 +0200 Subject: [PATCH 60/62] histo + lines (only .dat are ready) --- communication_techniques/parsing.sh | 115 ++++++++++++++++++++-------- 1 file changed, 81 insertions(+), 34 deletions(-) diff --git a/communication_techniques/parsing.sh b/communication_techniques/parsing.sh index c764048..485aee1 100755 --- a/communication_techniques/parsing.sh +++ b/communication_techniques/parsing.sh @@ -2,12 +2,14 @@ set -u -#comList = `ls | perl -pi -e 's/.*-(\w+)_com/$1/' | sort | uniq` +#barriereList="jikes_barrier asm_cache c_cache fake" +barriereList="jikes_barrier asm_cache c_cache" +communicationList="asm_cache c_cache shared_mem shared_mem_opt pipe" comList=`ls *.log | perl -ni -e '/-([^-]+)_comm/; $a{$1}=""; END { foreach ( sort keys %a ) {print "$_ "}}'` cacheList=`ls *log | perl -ni -e '/cache_([^-]+)-/; $a{$1}=""; END { foreach ( sort keys %a ) {print "$_ "}}'` prodList=`ls *.log | perl -ni -e '/typeProd_([^-]+)-/; $a{$1}=""; END { foreach ( sort keys %a ) {print "$_ "}}'` -barriereList="jikes_barrier asm_cache c_cache fake" -communicationList="asm_cache c_cache shared_mem shared_mem_opt pipe" +barriereCommaList=`echo $barriereList | sed "s/ /,/g"` +argTypeProdList=`eval ls *typeProd_useless_loop*{$barriereCommaList}_comm.log | perl -ni -e '/argTypeProd_([\d]+)-/; $a{$1}=""; END { foreach ( sort { $a <=> $b } keys %a ) {print "$_ "}}'` metriqueList="cache_hits cache_miss cycles total_time" @@ -20,40 +22,84 @@ echo "set bmargin 5" >> multicores.gnuplot echo "set terminal postscript landscape color" >> multicores.gnuplot for prod in $prodList ; do + case "$prod" in + matrice) argTypeProd=16 ;; + *) argTypeProd=1 ;; + esac for bench in "communication" "barriere" ; do for metrique in $metriqueList ; do - > bench_$bench-prod_$prod-$metrique.dat - for file in cache_$cache-*-typeProd_$prod-*-${com}_comm.log ; do - argTypeProd=`echo "$file" | sed -r "s/.*argTypeProd_([[:digit:]]+).*/\1/"` - echo -ne "\t\t$argTypeProd" >> bench_$bench-prod_$prod-$metrique.dat - done + > bench_$bench-prod_$prod-metrique_$metrique.dat + if [ $bench = "communication" -o $prod != "useless_loop" ] ; then + echo -ne "Method\t\t" >> bench_$bench-prod_$prod-metrique_$metrique.dat + for cache in $cacheList ; do + echo -ne "\t$cache" >> bench_$bench-prod_$prod-metrique_$metrique.dat + done + else + echo -ne "argTypeProd\t\t" >> bench_$bench-prod_$prod-metrique_$metrique.dat + for com in `eval echo \\\$\${bench}List` ; do + echo -ne "\t$com" >> bench_$bench-prod_$prod-metrique_$metrique.dat + done + echo "" >> bench_$bench-prod_$prod-metrique_$metrique.dat + fi + # for file in cache_$cache-*-typeProd_$prod-*-${com}_comm.log ; do + # argTypeProd=`echo "$file" | sed -r "s/.*argTypeProd_([[:digit:]]+).*/\1/"` + # echo -ne "\t\t$argTypeProd" >> bench_$bench-prod_$prod-$metrique.dat + # done done - for com in `eval echo \\\$\${bench}List` ; do - for metrique in $metriqueList ; do - echo -ne "\n$com\t\t" >> bench_$bench-prod_$prod-$metrique.dat + if [ $bench = "communication" -o $prod != "useless_loop" ] ; then + for com in `eval echo \\\$\${bench}List` ; do + for metrique in $metriqueList ; do + case "$metrique" in + cache_hits) metriquePattern="cache hits" ;; + cache_miss) metriquePattern="cache miss" ;; + cycles) metriquePattern="cycles" ;; + total_time) metriquePattern="total_time" ;; + *) echo "Pas de pattern pour cette métrique : $metrique" ; exit 1 ;; + esac + for i in 1 2 3 ; do # 1: total, 2: by loop, 3: by write + echo -ne "\n$com\t\t" >> bench_$bench-prod_$prod-metrique_$metrique.dat + for cache in $cacheList ; do + if [ $i -eq 1 ] + then + eval value$cache=\"`perl -n -e "print \"\\$1 \\$2 \\$3 \" if /$metriquePattern.* (\S+) \/ (\S+) \/ (\S+)/" cache_$cache-*-typeProd_$prod-argTypeProd_$argTypeProd-*-${com}_comm.log`\" + fi + eval echo -ne "\${value$cache}" | cut -d ' ' -f $i | sed -r 's/(.*)/\t\1/' | tr -d '\n' >> bench_$bench-prod_$prod-metrique_$metrique.dat + done + done + done done - for cache in $cacheList ; do - for value in `perl -n -e 'print "$1 $2 $3 " if /cache hits.* (\d+) \/ (\S+) \/ (\S+)/' cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do - echo -ne "\t$value " >> bench_$bench-prod_$prod-cache_hits.dat - done - for value in `perl -n -e 'print "$1 $2 $3 " if /cache miss.* (\d+) \/ (\S+) \/ (\S+)/' cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do - echo -ne "\t$value" >> bench_$bench-prod_$prod-cache_miss.dat - done - for value in `perl -n -e 'print "$1 $2 $3 " if /cycles.* (\d+) \/ (\S+) \/ (\S+)/' cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do - echo -ne "\t$value" >> bench_$bench-prod_$prod-cycles.dat - done - for value in `perl -n -e 'print "$1 $2 $3 " if /total_time.* (\S+) \/ (\S+) \/ (\S+)/' cache_$cache-*-typeProd_$prod-*-${com}_comm.log` ; do - echo -ne "\t$value" >> bench_$bench-prod_$prod-total_time.dat - done - - done - done - if [ "${bench}" = "barriere" ] ; - then - echo "set style data lines" >> multicores.gnuplot else - echo "set style data histogram" >> multicores.gnuplot + for metrique in $metriqueList ; do + case "$metrique" in + cache_hits) metriquePattern="cache hits" ;; + cache_miss) metriquePattern="cache miss" ;; + cycles) metriquePattern="cycles" ;; + total_time) metriquePattern="total_time" ;; + *) echo "Pas de pattern pour cette métrique : $metrique" ; exit 1 ;; + esac + for argTypeProd in $argTypeProdList ; do + for cache in $cacheList ; do + echo "" >> bench_$bench-prod_$prod-metrique_$metrique.dat + for i in 1 2 3 ; do # 1: total, 2: by loop, 3: by write + echo -ne "\n$argTypeProd\t\t" >> bench_$bench-prod_$prod-metrique_$metrique.dat + for com in `eval echo \\\$\${bench}List` ; do + if [ $i -eq 1 ] + then + eval value$com=\"`perl -n -e "print \"\\$1 \\$2 \\$3 \" if /$metriquePattern.* (\S+) \/ (\S+) \/ (\S+)/" cache_$cache-*-typeProd_$prod-argTypeProd_$argTypeProd-*-${com}_comm.log`\" + fi + eval echo -ne "\${value$com}" | cut -d ' ' -f $i | sed -r 's/(.*)/\t\1/' | tr -d '\n' >> bench_$bench-prod_$prod-metrique_$metrique.dat + done + done + done + done + done fi + if [ "${bench}" != "barriere" ] ; + then + # echo "set style data lines" >> multicores.gnuplot + #else + echo "set style data histogram" >> multicores.gnuplot + #fi for metrique in $metriqueList ; do case "$metrique" in cache_hits) ylabel="Nb cache hit" ;; @@ -70,15 +116,16 @@ for prod in $prodList ; do echo "set title \"Producteur : $prod\"" >> multicores.gnuplot echo "set ylabel \"$ylabel\"" >> multicores.gnuplot echo "set output 'bench_$bench-prod_$prod-$metrique-total-$yscale.ps'" >> multicores.gnuplot - echo "plot 'bench_$bench-prod_$prod-$metrique.dat' using 2:xtic(1) ti 'L2', '' u 5 ti 'MEM'" >> multicores.gnuplot + echo "plot 'bench_$bench-prod_$prod-metrique_$metrique.dat' every 3:1 using 2:xtic(1) title 2 , '' every 3:1 u 3 ti 3" >> multicores.gnuplot echo "set ylabel \"$ylabel par boucle\"" >> multicores.gnuplot echo "set output 'bench_$bench-prod_$prod-$metrique-byLoop-$yscale.ps'" >> multicores.gnuplot - echo "plot 'bench_$bench-prod_$prod-$metrique.dat' using 3:xtic(1) ti 'L2', '' u 6 ti 'MEM'" >> multicores.gnuplot + echo "plot 'bench_$bench-prod_$prod-metrique_$metrique.dat' every 3:2 using 2:xtic(1) title 2 , '' every 3:2 u 3 ti 3" >> multicores.gnuplot echo "set ylabel \"$ylabel par ecriture\"" >> multicores.gnuplot echo "set output 'bench_$bench-prod_$prod-$metrique-byWrite-$yscale.ps'" >> multicores.gnuplot - echo "plot 'bench_$bench-prod_$prod-$metrique.dat' using 4:xtic(1) ti 'L2', '' u 7 ti 'MEM'" >> multicores.gnuplot + echo "plot 'bench_$bench-prod_$prod-metrique_$metrique.dat' every 3:3 using 2:xtic(1) title 2 , '' every 3:3 u 3 ti 3" >> multicores.gnuplot done done + fi done done From baff7d6b6e0706ed55c289eded0b4285d9dfbc6e Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Tue, 23 Feb 2010 11:35:25 +0100 Subject: [PATCH 61/62] [Comm tech bench] Some parsing.sh debug - Correct some gnuplot "every" misuse - Don't skip 2 lines for useless_loop - Try to deal with xticlabels => Need a refactoring to have 1 gnuplot file per output --- communication_techniques/parsing.sh | 66 ++++++++++++++++++----------- 1 file changed, 42 insertions(+), 24 deletions(-) diff --git a/communication_techniques/parsing.sh b/communication_techniques/parsing.sh index 485aee1..e1d9820 100755 --- a/communication_techniques/parsing.sh +++ b/communication_techniques/parsing.sh @@ -27,24 +27,22 @@ for prod in $prodList ; do *) argTypeProd=1 ;; esac for bench in "communication" "barriere" ; do + # Create dat headers for metrique in $metriqueList ; do > bench_$bench-prod_$prod-metrique_$metrique.dat + # Compare shared L2 to shared mem if [ $bench = "communication" -o $prod != "useless_loop" ] ; then echo -ne "Method\t\t" >> bench_$bench-prod_$prod-metrique_$metrique.dat for cache in $cacheList ; do echo -ne "\t$cache" >> bench_$bench-prod_$prod-metrique_$metrique.dat done + # Compare barrier type else echo -ne "argTypeProd\t\t" >> bench_$bench-prod_$prod-metrique_$metrique.dat - for com in `eval echo \\\$\${bench}List` ; do + for com in $barriereList ; do echo -ne "\t$com" >> bench_$bench-prod_$prod-metrique_$metrique.dat done - echo "" >> bench_$bench-prod_$prod-metrique_$metrique.dat fi - # for file in cache_$cache-*-typeProd_$prod-*-${com}_comm.log ; do - # argTypeProd=`echo "$file" | sed -r "s/.*argTypeProd_([[:digit:]]+).*/\1/"` - # echo -ne "\t\t$argTypeProd" >> bench_$bench-prod_$prod-$metrique.dat - # done done if [ $bench = "communication" -o $prod != "useless_loop" ] ; then for com in `eval echo \\\$\${bench}List` ; do @@ -79,7 +77,9 @@ for prod in $prodList ; do esac for argTypeProd in $argTypeProdList ; do for cache in $cacheList ; do - echo "" >> bench_$bench-prod_$prod-metrique_$metrique.dat + if [ $cache != ${cacheList%% *} -o $argTypeProd != ${argTypeProdList%% *} ] ; then + echo "" >> bench_$bench-prod_$prod-metrique_$metrique.dat + fi for i in 1 2 3 ; do # 1: total, 2: by loop, 3: by write echo -ne "\n$argTypeProd\t\t" >> bench_$bench-prod_$prod-metrique_$metrique.dat for com in `eval echo \\\$\${bench}List` ; do @@ -94,12 +94,11 @@ for prod in $prodList ; do done done fi - if [ "${bench}" != "barriere" ] ; - then - # echo "set style data lines" >> multicores.gnuplot - #else + if [ $bench = "communication" -o $prod != "useless_loop" ] ; then echo "set style data histogram" >> multicores.gnuplot - #fi + else + echo "set style data lines" >> multicores.gnuplot + fi for metrique in $metriqueList ; do case "$metrique" in cache_hits) ylabel="Nb cache hit" ;; @@ -114,18 +113,39 @@ for prod in $prodList ; do [ "$yscale" = "nologscale" ] && echo "set yrange [0:*]" >> multicores.gnuplot \ || echo "set yrange [*:*]" >> multicores.gnuplot echo "set title \"Producteur : $prod\"" >> multicores.gnuplot - echo "set ylabel \"$ylabel\"" >> multicores.gnuplot - echo "set output 'bench_$bench-prod_$prod-$metrique-total-$yscale.ps'" >> multicores.gnuplot - echo "plot 'bench_$bench-prod_$prod-metrique_$metrique.dat' every 3:1 using 2:xtic(1) title 2 , '' every 3:1 u 3 ti 3" >> multicores.gnuplot - echo "set ylabel \"$ylabel par boucle\"" >> multicores.gnuplot - echo "set output 'bench_$bench-prod_$prod-$metrique-byLoop-$yscale.ps'" >> multicores.gnuplot - echo "plot 'bench_$bench-prod_$prod-metrique_$metrique.dat' every 3:2 using 2:xtic(1) title 2 , '' every 3:2 u 3 ti 3" >> multicores.gnuplot - echo "set ylabel \"$ylabel par ecriture\"" >> multicores.gnuplot - echo "set output 'bench_$bench-prod_$prod-$metrique-byWrite-$yscale.ps'" >> multicores.gnuplot - echo "plot 'bench_$bench-prod_$prod-metrique_$metrique.dat' every 3:3 using 2:xtic(1) title 2 , '' every 3:3 u 3 ti 3" >> multicores.gnuplot + if [ $bench = "communication" -o $prod != "useless_loop" ] ; then + echo "set ylabel \"$ylabel\"" >> multicores.gnuplot + echo "set output 'bench_$bench-prod_$prod-$metrique-total-$yscale.ps'" >> multicores.gnuplot + echo "plot 'bench_$bench-prod_$prod-metrique_$metrique.dat' every 3::1 using 2:xtic(1) title 2 , '' every 3::1 u 3 ti 3" >> multicores.gnuplot + if [ $metrique != "total_time" -o $yscale != "logscale" ] ; then + echo "set ylabel \"$ylabel par boucle\"" >> multicores.gnuplot + echo "set output 'bench_$bench-prod_$prod-$metrique-byLoop-$yscale.ps'" >> multicores.gnuplot + echo "plot 'bench_$bench-prod_$prod-metrique_$metrique.dat' every 3::2 using 2:xtic(1) title 2 , '' every 3::2 u 3 ti 3" >> multicores.gnuplot + echo "set ylabel \"$ylabel par ecriture\"" >> multicores.gnuplot + echo "set output 'bench_$bench-prod_$prod-$metrique-byWrite-$yscale.ps'" >> multicores.gnuplot + echo "plot 'bench_$bench-prod_$prod-metrique_$metrique.dat' every 3::3 using 2:xtic(1) title 2 , '' every 3::3 u 3 ti 3" >> multicores.gnuplot + fi + else + columnNo=2 + for com in `eval echo \\\$\${bench}List` ; do + baseTitle=`head -1 bench_$bench-prod_$prod-metrique_$metrique.dat | cut -f $((columnNo + 2))` + echo "set xtics" >> multicores.gnuplot + echo "set ylabel \"$ylabel\"" >> multicores.gnuplot + echo "set output 'bench_$bench-prod_$prod-$metrique-total-$yscale.ps'" >> multicores.gnuplot + echo "plot 'bench_$bench-prod_$prod-metrique_$metrique.dat' every :2:0:0:0 using 1:$columnNo:xtic(1) title '$baseTitle (L2)', '' every :2:0:1:0 using 1:$columnNo:xtic(1) title '$baseTitle (mem)'" >> multicores.gnuplot + if [ $metrique != "total_time" -o $yscale != "logscale" ] ; then + echo "set ylabel \"$ylabel par boucle\"" >> multicores.gnuplot + echo "set output 'bench_$bench-prod_$prod-$metrique-byLoop-$yscale.ps'" >> multicores.gnuplot + echo "plot 'bench_$bench-prod_$prod-metrique_$metrique.dat' every :2:1:0:1 using 1:$columnNo:xtic(1) title '$baseTitle (L2)', '' every :2:1:1:1 using 1:$columnNo:xtic(1) title '$baseTitle (mem)'" >> multicores.gnuplot + echo "set ylabel \"$ylabel par ecriture\"" >> multicores.gnuplot + echo "set output 'bench_$bench-prod_$prod-$metrique-byWrite-$yscale.ps'" >> multicores.gnuplot + echo "plot 'bench_$bench-prod_$prod-metrique_$metrique.dat' every :2:2:0:2 using 1:$columnNo:xtic(1) title '$baseTitle (L2)', '' every :2:2:1:2 using 1:$columnNo:xtic(1) title '$baseTitle (mem)'" >> multicores.gnuplot + fi + columnNo=$((columnNo + 1)) + done + fi done done - fi done done @@ -134,5 +154,3 @@ gnuplot multicores.gnuplot for f in *.ps ; do ps2pdf $f done - -acroread *.pdf From ad804e4a5a688ef215346f25485ba81a3f4f40d9 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Thu, 25 Feb 2010 17:21:45 +0100 Subject: [PATCH 62/62] [comm tech bench] 1 gnuplot per graph - Refactor parsing.sh to have one gnuplot file per graph - Change the set style data from lines to linespoints - Add one title per series of point (one for each every) in dat headers --- communication_techniques/parsing.sh | 410 ++++++++++++++++++++-------- 1 file changed, 292 insertions(+), 118 deletions(-) diff --git a/communication_techniques/parsing.sh b/communication_techniques/parsing.sh index e1d9820..1da8dbb 100755 --- a/communication_techniques/parsing.sh +++ b/communication_techniques/parsing.sh @@ -21,6 +21,271 @@ echo "set xtic rotate by -45" >> multicores.gnuplot echo "set bmargin 5" >> multicores.gnuplot echo "set terminal postscript landscape color" >> multicores.gnuplot +use_histo () +{ + local prod bench + prod="$1" + bench="$2" + + [ "$bench" = "communication" -o "$prod" != "useless_loop" ] + return $? +} + +create_dat_header () +{ + local prod bench metrique + prod="$1" + bench="$2" + metrique="$3" + + # Create file + > bench_$bench-prod_$prod-metrique_$metrique.dat + + # Only one point per com and cache + if use_histo "$prod" "$bench" + then + for i in 1 2 3 # 1: total, 2: by loop, 3: by write + do + if [ $i -ne 1 ] + then + echo >> bench_$bench-prod_$prod-metrique_$metrique.dat + fi + echo -ne "Method\t\t" >> bench_$bench-prod_$prod-metrique_$metrique.dat + for cache in $cacheList + do + echo -ne "\t$cache" >> bench_$bench-prod_$prod-metrique_$metrique.dat + done + done + # Several points per com and cache (one per calc argument) + else + for i in 1 2 + do + if [ $i -ne 1 ] + then + echo >> bench_$bench-prod_$prod-metrique_$metrique.dat + fi + for j in 1 2 3 # 1: total, 2: by loop, 3: by write + do + echo -ne "argTypeProd\t\t" >> bench_$bench-prod_$prod-metrique_$metrique.dat + for com in $barriereList + do + echo -ne "\t$com" >> bench_$bench-prod_$prod-metrique_$metrique.dat + done + echo >> bench_$bench-prod_$prod-metrique_$metrique.dat + done + done + fi +} + +get_metric_values () +{ + local prod com cache argTypeProd logFile + prod="$1" + com="$2" + cache="$3" + argTypeProd="$4" + metriquePattern="$5" + + logFile=cache_$cache-*-typeProd_$prod-argTypeProd_$argTypeProd-*-${com}_comm.log + perl -n -e "print \"\$1 \$2 \$3 \" if /$metriquePattern.* (\S+) \/ (\S+) \/ (\S+)/" $logFile +} + +create_simple_dat_body () +{ + local prod bench metrique argTypeProd + prod="$1" + bench="$2" + metrique="$3" + argTypeProd="$4" + + for com in `eval echo \\\$\${bench}List` + do + for i in 1 2 3 # 1: total, 2: by loop, 3: by write + do + echo -ne "\n$com\t\t" >> bench_$bench-prod_$prod-metrique_$metrique.dat + for cache in $cacheList + do + if [ $i -eq 1 ] + then + valuetmp=`get_metric_values "$prod" "$com" "$cache" "$argTypeProd" "$metriquePattern"` + eval value$cache=\"$valuetmp\" + fi + eval echo -ne "\${value$cache}" | sed -r "s/^([^ ]+ ){$((i-1))}([^ ]+).*/\t\2/" >> bench_$bench-prod_$prod-metrique_$metrique.dat + done + done + done +} + +create_complex_dat_body () +{ + local prod bench metrique + prod="$1" + bench="$2" + metrique="$3" + + for argTypeProd in $argTypeProdList + do + for cache in $cacheList + do + if [ $cache != ${cacheList%% *} -o $argTypeProd != ${argTypeProdList%% *} ] + then + echo "" >> bench_$bench-prod_$prod-metrique_$metrique.dat + fi + for i in 1 2 3 # 1: total, 2: by loop, 3: by write + do + echo -ne "\n$argTypeProd\t\t" >> bench_$bench-prod_$prod-metrique_$metrique.dat + for com in `eval echo \\\$\${bench}List` + do + if [ $i -eq 1 ] + then + valuetmp=`get_metric_values "$prod" "$com" "$cache" "$argTypeProd" "$metriquePattern"` + eval value$com=\"$valuetmp\" + fi + eval echo -ne "\${value$com}" | sed -r "s/^([^ ]+ ){$((i-1))}([^ ]+).*/\t\2/" >> bench_$bench-prod_$prod-metrique_$metrique.dat + done + done + done + done +} + +create_dat_body () +{ + local prod bench metrique argTypeProd + prod="$1" + bench="$2" + metrique="$3" + argTypeProd="$4" + + if use_histo "$prod" "$bench" + then + create_simple_dat_body "$prod" "$bench" "$metrique" "$argTypeProd" "$metriquePattern" + else + create_complex_dat_body "$prod" "$bench" "$metrique" "$argTypeProd" "$metriquePattern" + fi +} + +create_gnuplot_header () +{ + local prod bench gnuplotFile + prod="$1" + bench="$2" + gnuplotFile="$3" + + echo "set style fill solid border -1" > $gnuplotFile + echo "set boxwidth 0.9" >> $gnuplotFile + echo "set xtic rotate by -45" >> $gnuplotFile + echo "set bmargin 5" >> $gnuplotFile + echo "set terminal postscript landscape color" >> $gnuplotFile + if use_histo "$prod" "$bench" + then + echo "set style data histogram" >> $gnuplotFile + echo "set style histogram cluster gap 1" >> $gnuplotFile + else + echo "set style data linespoints" >> $gnuplotFile + fi +} + +create_simple_gnuplot_body () +{ + local metrique ylabel yscale patternPlotFile datFile + ylabel="$1" + lineNum="$2" + datFile="$3" + patternPlotFile="$4" + + echo "set ylabel \"$ylabel\"" >> $patternPlotFile.gnuplot + echo "set output '$patternPlotFile.ps'" >> $patternPlotFile.gnuplot + echo "plot '$datFile' every 3::$lineNum using 2:xtic(1) title 2 , '' every 3::$lineNum u 3 ti 3" >> $patternPlotFile.gnuplot +} + +create_complex_gnuplot_body () +{ + local bench ylabel lineNum datFile patternPlotFile columnNo baseTitle + bench="$1" + ylabel="$2" + lineNum="$3" + datFile="$4" + patternPlotFile="$5" + columnNo=2 + + echo "set ylabel \"$ylabel\"" >> $patternPlotFile.gnuplot + echo "set output '$patternPlotFile.ps'" >> $patternPlotFile.gnuplot + for com in `eval echo \\\$\${bench}List` ; do + baseTitle=`head -1 $datFile | cut -f $((columnNo + 2))` + if [ $columnNo -ne 2 ] + then + echo -n ", '' " >> $patternPlotFile.gnuplot + else + echo -n "plot '$datFile' " >> $patternPlotFile.gnuplot + fi + echo -n "every :2:$lineNum:0:$lineNum using 1:$columnNo:xtic(1) title '$baseTitle (L2)'" >> $patternPlotFile.gnuplot + echo -n ", '' every :2:$lineNum:1:$lineNum using 1:$columnNo:xtic(1) title '$baseTitle (mem)'" >> $patternPlotFile.gnuplot + columnNo=$((columnNo + 1)) + done + echo >> $patternPlotFile.gnuplot +} + +create_gnuplot_body () +{ + local prod bench yscale ylabel lineNum datFile patternPlotFile + prod="$1" + bench="$2" + yscale="$3" + ylabel="$4" + lineNum="$5" + datFile="$6" + patternPlotFile="$7" + + echo "set $yscale y" >> $patternPlotFile.gnuplot + if [ "$yscale" = "nologscale" ] + then + echo "set yrange [0:*]" >> $patternPlotFile.gnuplot + else + echo "set yrange [*:*]" >> $patternPlotFile.gnuplot + fi + echo "set title \"Producteur : $prod\"" >> $patternPlotFile.gnuplot + if use_histo "$prod" "$bench" + then + create_simple_gnuplot_body "$ylabel" "$lineNum" "$datFile" "$patternPlotFile" + else + create_complex_gnuplot_body "$bench" "$ylabel" "$lineNum" "$datFile" "$patternPlotFile" + fi +} + +create_gnuplot_file () +{ + local prod bench metrique ylabel yscale avg lineNum + prod="$1" + bench="$2" + metrique="$3" + baseYlabel="$4" + + for yscale in "nologscale" "logscale" + do + for avg in total byLoop byWrite + do + case $avg in + total) + lineNum=0 + ylabel="$baseYlabel" ;; + byLoop) + lineNum=1 + ylabel="$baseYlabel par boucle" ;; + byWrite) + lineNum=2 + ylabel="$baseYlabel par ecriture" ;; + esac + datFile=bench_$bench-prod_$prod-metrique_$metrique.dat + patternPlotFile="bench_$bench-prod_$prod-$metrique-$avg-$yscale" # Name without extension of plot and ps files + create_gnuplot_header "$prod" "$bench" "$patternPlotFile.gnuplot" + if [ $metrique != "total_time" -o $yscale != "logscale" ] + then + create_gnuplot_body "$prod" "$bench" "$yscale" "$ylabel" "$lineNum" "$datFile" "$patternPlotFile" + fi + done + done +} + for prod in $prodList ; do case "$prod" in matrice) argTypeProd=16 ;; @@ -28,129 +293,38 @@ for prod in $prodList ; do esac for bench in "communication" "barriere" ; do # Create dat headers - for metrique in $metriqueList ; do - > bench_$bench-prod_$prod-metrique_$metrique.dat - # Compare shared L2 to shared mem - if [ $bench = "communication" -o $prod != "useless_loop" ] ; then - echo -ne "Method\t\t" >> bench_$bench-prod_$prod-metrique_$metrique.dat - for cache in $cacheList ; do - echo -ne "\t$cache" >> bench_$bench-prod_$prod-metrique_$metrique.dat - done - # Compare barrier type - else - echo -ne "argTypeProd\t\t" >> bench_$bench-prod_$prod-metrique_$metrique.dat - for com in $barriereList ; do - echo -ne "\t$com" >> bench_$bench-prod_$prod-metrique_$metrique.dat - done - fi - done - if [ $bench = "communication" -o $prod != "useless_loop" ] ; then - for com in `eval echo \\\$\${bench}List` ; do - for metrique in $metriqueList ; do - case "$metrique" in - cache_hits) metriquePattern="cache hits" ;; - cache_miss) metriquePattern="cache miss" ;; - cycles) metriquePattern="cycles" ;; - total_time) metriquePattern="total_time" ;; - *) echo "Pas de pattern pour cette métrique : $metrique" ; exit 1 ;; - esac - for i in 1 2 3 ; do # 1: total, 2: by loop, 3: by write - echo -ne "\n$com\t\t" >> bench_$bench-prod_$prod-metrique_$metrique.dat - for cache in $cacheList ; do - if [ $i -eq 1 ] - then - eval value$cache=\"`perl -n -e "print \"\\$1 \\$2 \\$3 \" if /$metriquePattern.* (\S+) \/ (\S+) \/ (\S+)/" cache_$cache-*-typeProd_$prod-argTypeProd_$argTypeProd-*-${com}_comm.log`\" - fi - eval echo -ne "\${value$cache}" | cut -d ' ' -f $i | sed -r 's/(.*)/\t\1/' | tr -d '\n' >> bench_$bench-prod_$prod-metrique_$metrique.dat - done - done - done - done - else - for metrique in $metriqueList ; do - case "$metrique" in - cache_hits) metriquePattern="cache hits" ;; - cache_miss) metriquePattern="cache miss" ;; - cycles) metriquePattern="cycles" ;; - total_time) metriquePattern="total_time" ;; - *) echo "Pas de pattern pour cette métrique : $metrique" ; exit 1 ;; - esac - for argTypeProd in $argTypeProdList ; do - for cache in $cacheList ; do - if [ $cache != ${cacheList%% *} -o $argTypeProd != ${argTypeProdList%% *} ] ; then - echo "" >> bench_$bench-prod_$prod-metrique_$metrique.dat - fi - for i in 1 2 3 ; do # 1: total, 2: by loop, 3: by write - echo -ne "\n$argTypeProd\t\t" >> bench_$bench-prod_$prod-metrique_$metrique.dat - for com in `eval echo \\\$\${bench}List` ; do - if [ $i -eq 1 ] - then - eval value$com=\"`perl -n -e "print \"\\$1 \\$2 \\$3 \" if /$metriquePattern.* (\S+) \/ (\S+) \/ (\S+)/" cache_$cache-*-typeProd_$prod-argTypeProd_$argTypeProd-*-${com}_comm.log`\" - fi - eval echo -ne "\${value$com}" | cut -d ' ' -f $i | sed -r 's/(.*)/\t\1/' | tr -d '\n' >> bench_$bench-prod_$prod-metrique_$metrique.dat - done - done - done - done - done - fi - if [ $bench = "communication" -o $prod != "useless_loop" ] ; then - echo "set style data histogram" >> multicores.gnuplot - else - echo "set style data lines" >> multicores.gnuplot - fi for metrique in $metriqueList ; do case "$metrique" in - cache_hits) ylabel="Nb cache hit" ;; - cache_miss) ylabel="Nb cache miss" ;; - cycles) ylabel="Nb cycles" ;; - total_time) ylabel="Secondes" ;; - *) echo "Pas de label pour cette métrique : $metrique" ; exit 1 ;; + cache_hits) + metriquePattern="cache hits" + ylabel="Nb cache hit" ;; + cache_miss) + metriquePattern="cache miss" + ylabel="Nb cache miss" ;; + cycles) + metriquePattern="cycles" + ylabel="Nb cycles" ;; + total_time) + metriquePattern="total_time" + ylabel="Secondes" ;; + *) + echo "Pas de pattern pour cette métrique : $metrique" + echo "Pas de label pour cette métrique : $metrique" + exit 1 ;; esac - - for yscale in "nologscale" "logscale" ; do - echo "set $yscale y" >> multicores.gnuplot - [ "$yscale" = "nologscale" ] && echo "set yrange [0:*]" >> multicores.gnuplot \ - || echo "set yrange [*:*]" >> multicores.gnuplot - echo "set title \"Producteur : $prod\"" >> multicores.gnuplot - if [ $bench = "communication" -o $prod != "useless_loop" ] ; then - echo "set ylabel \"$ylabel\"" >> multicores.gnuplot - echo "set output 'bench_$bench-prod_$prod-$metrique-total-$yscale.ps'" >> multicores.gnuplot - echo "plot 'bench_$bench-prod_$prod-metrique_$metrique.dat' every 3::1 using 2:xtic(1) title 2 , '' every 3::1 u 3 ti 3" >> multicores.gnuplot - if [ $metrique != "total_time" -o $yscale != "logscale" ] ; then - echo "set ylabel \"$ylabel par boucle\"" >> multicores.gnuplot - echo "set output 'bench_$bench-prod_$prod-$metrique-byLoop-$yscale.ps'" >> multicores.gnuplot - echo "plot 'bench_$bench-prod_$prod-metrique_$metrique.dat' every 3::2 using 2:xtic(1) title 2 , '' every 3::2 u 3 ti 3" >> multicores.gnuplot - echo "set ylabel \"$ylabel par ecriture\"" >> multicores.gnuplot - echo "set output 'bench_$bench-prod_$prod-$metrique-byWrite-$yscale.ps'" >> multicores.gnuplot - echo "plot 'bench_$bench-prod_$prod-metrique_$metrique.dat' every 3::3 using 2:xtic(1) title 2 , '' every 3::3 u 3 ti 3" >> multicores.gnuplot - fi - else - columnNo=2 - for com in `eval echo \\\$\${bench}List` ; do - baseTitle=`head -1 bench_$bench-prod_$prod-metrique_$metrique.dat | cut -f $((columnNo + 2))` - echo "set xtics" >> multicores.gnuplot - echo "set ylabel \"$ylabel\"" >> multicores.gnuplot - echo "set output 'bench_$bench-prod_$prod-$metrique-total-$yscale.ps'" >> multicores.gnuplot - echo "plot 'bench_$bench-prod_$prod-metrique_$metrique.dat' every :2:0:0:0 using 1:$columnNo:xtic(1) title '$baseTitle (L2)', '' every :2:0:1:0 using 1:$columnNo:xtic(1) title '$baseTitle (mem)'" >> multicores.gnuplot - if [ $metrique != "total_time" -o $yscale != "logscale" ] ; then - echo "set ylabel \"$ylabel par boucle\"" >> multicores.gnuplot - echo "set output 'bench_$bench-prod_$prod-$metrique-byLoop-$yscale.ps'" >> multicores.gnuplot - echo "plot 'bench_$bench-prod_$prod-metrique_$metrique.dat' every :2:1:0:1 using 1:$columnNo:xtic(1) title '$baseTitle (L2)', '' every :2:1:1:1 using 1:$columnNo:xtic(1) title '$baseTitle (mem)'" >> multicores.gnuplot - echo "set ylabel \"$ylabel par ecriture\"" >> multicores.gnuplot - echo "set output 'bench_$bench-prod_$prod-$metrique-byWrite-$yscale.ps'" >> multicores.gnuplot - echo "plot 'bench_$bench-prod_$prod-metrique_$metrique.dat' every :2:2:0:2 using 1:$columnNo:xtic(1) title '$baseTitle (L2)', '' every :2:2:1:2 using 1:$columnNo:xtic(1) title '$baseTitle (mem)'" >> multicores.gnuplot - fi - columnNo=$((columnNo + 1)) - done - fi - done + create_dat_header "$prod" "$bench" "$metrique" + create_dat_body "$prod" "$bench" "$metrique" "$argTypeProd" "$metriquePattern" + create_gnuplot_file "$prod" "$bench" "$metrique" "$ylabel" done done done -gnuplot multicores.gnuplot - -for f in *.ps ; do - ps2pdf $f +for gnuplotFile in *.gnuplot +do + gnuplot "$gnuplotFile" +done + +for psFile in *.ps +do + ps2pdf $psFile done