#ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include "config.h" #include #include #include #include #include #include #include #include #include #include #include "test_params.h" typedef cpu_set_t ProcMaskType; int long long num_rep_max; pthread_attr_t attr; pthread_barrier_t bar; pthread_mutex_t mutexsum = PTHREAD_MUTEX_INITIALIZER; int long long ** __attribute__((aligned(64))) cycles_s, ** __attribute__((aligned(64))) cycles_e; pid_t get_thread_id() { return syscall(__NR_gettid); } int bind_thread_to_core(int core_id) { int error; pid_t thread_id; cpu_set_t affinity_mask; CPU_ZERO(&affinity_mask); CPU_SET(core_id, &affinity_mask); thread_id = get_thread_id(); error = sched_setaffinity(thread_id, sizeof(affinity_mask), &affinity_mask); if (error) { printf ("sched_setaffinity failed\n"); return 0; } return 1; } inline __attribute__((always_inline)) void sleep0(){ sched_yield(); } void set_process_priority_high(){ setpriority(PRIO_PROCESS, 0, PRIO_MIN); } void set_process_priority_normal(){ setpriority(PRIO_PROCESS, 0, 0); } double POM[NUM_THREADS*(L1CACHESIZE+L2CACHESIZE+L3CACHESIZE)/8]; inline __attribute__((always_inline)) void clear_cache_deep(){ unsigned int i; for (i = 0; i < (NUM_THREADS*(L1CACHESIZE+L2CACHESIZE+L3CACHESIZE)/sizeof(double)); i++){ POM[i] = 3.14*i; } } int long long median(int n, int long long x[]){ int long long temp; int i, j; for(i=0; i 1 pthread_barrier_wait(&bar); #endif num_reps_t = NUM_RUNS*3; serialize(); tsc_s = read_tsc_start(); //CALCULATE NUMBER ITERATIONS FOR TEST CODE TO EXECUTE DURING EXPECTED TIME test_function(test_var,num_reps_t); tsc_e = read_tsc_end(); int long long number_rep_aux = (int long long) ceil( (double) expected_time*FREQUENCY*num_reps_t/(tsc_e-tsc_s)); #if NUM_THREADS > 1 pthread_mutex_lock (&mutexsum); #endif if(num_rep_max < number_rep_aux){ num_rep_max = number_rep_aux; } #if NUM_THREADS > 1 pthread_mutex_unlock (&mutexsum); #endif num_reps_t = num_rep_max; serialize(); #if NUM_THREADS > 1 pthread_barrier_wait(&bar); sleep0(); #endif serialize(); //REPEAT EACH TEST BY NUM_RUNS TO REPORT MEDIAN IN THE END for(i=0;i 1 pthread_barrier_wait(&bar); sleep0(); #endif serialize(); //READ TIME tsc_s = read_tsc_start(); test_function(test_var, num_reps_t); //READ COUNTERS tsc_e = read_tsc_end(); serialize(); cycles_s[tid][i] = tsc_s; cycles_e[tid][i] = tsc_e; serialize(); #if NUM_THREADS > 1 pthread_barrier_wait(&bar); sleep0(); #endif serialize(); } serialize(); #if defined (MEM) || defined (VAL) || defined (DIV) || defined (CARMDAHL) _mm_free(test_var); #endif pthread_exit(NULL); } void run_test(){ int i; int rc; pthread_t threads[NUM_THREADS]; long taskids[NUM_THREADS]; void * status; set_process_priority_high(); pthread_barrier_init(&bar,NULL,NUM_THREADS); //CREATE THREADS for(i = 0; i < NUM_THREADS; i++){ taskids[i] = i; rc = pthread_create(&threads[i], NULL, benchmark_test,(void *) taskids[i]); if (rc){ printf("ERROR; return code from pthread_create() is %d\n", rc); exit(-1); } } //JOIN THREADS for(i = 0; i < NUM_THREADS; i++){ rc = pthread_join(threads[i], &status); if (rc){ printf("ERROR; return code from pthread_join() is %d\n", rc); exit(-1); } } pthread_barrier_destroy(&bar); pthread_mutex_destroy(&mutexsum); set_process_priority_normal(); } int main(){ int i, j, k; num_rep_max = 0; cycles_s = (int long long **)malloc(NUM_THREADS*sizeof(int long long *)); cycles_e = (int long long **)malloc(NUM_THREADS*sizeof(int long long *)); for(i = 0; i < NUM_THREADS; i++){ cycles_s[i] = (int long long *)malloc(NUM_RUNS*sizeof(int long long)); cycles_e[i] = (int long long *)malloc(NUM_RUNS*sizeof(int long long)); } //RUN BENCHMARK run_test(); //PARSE ALL RESULTS FILE * output= fopen(RESULTS_FILE,"a"); int long long * min_cycles_start = calloc(NUM_RUNS,sizeof(int long long)); int long long * max_cycles_end = calloc(NUM_RUNS,sizeof(int long long)); //GET TOTAL EXECUTION TIME (TIME FROM THE START OF THE FIRST THREAD UNTIL THE END OF THE LAST THREAD) for(i=0;i max_cycles_end[i]) max_cycles_end[i] = cycles_e[j][i]; } max_cycles_end[i] = max_cycles_end[i] - min_cycles_start[i]; } //REPORT CLOCKS MEDIAN fprintf(output,"%f",(double) median(NUM_RUNS,max_cycles_end)); //REPORT THEORETICAL LD fprintf(output,"\t%lld",NUM_REP*NUM_LD*NUM_THREADS*num_rep_max); fprintf(output,"\t%lld\n",num_rep_max); //FREE ALL VARIABLES for(i=0;i