#ifndef _program_hpp_ #define _program_hpp_ #include "config.h" #include "TestThread.hpp" #include "EnsembleVariables.hpp" #include #include using namespace std; class Program { int nb_lines_uncached; int nb_threads; int tab_size; int nb_diff_ML, nb_diff_CL, line_size, cache_lines; EnsembleVariables * E; TestThread** threads; public: Program(int nb_procs, int nb_diff_ML, int nb_diff_CL, int nb_max_trans, int nb_max_insts, int line_size, int cache_lines) { nb_lines_uncached = 1; nb_threads = nb_procs; threads = new TestThread*[nb_threads]; tab_size = (cache_lines * line_size) * ((int) ceil((double) (nb_diff_ML + nb_lines_uncached) / (double) nb_diff_CL) - 1) + (nb_diff_CL * line_size); this->nb_diff_ML = nb_diff_ML; this->nb_diff_CL = nb_diff_CL; this->line_size = line_size; this->cache_lines = cache_lines; E = new EnsembleVariables(nb_diff_ML * line_size, nb_procs, nb_diff_CL, cache_lines, line_size, nb_lines_uncached, tab_size); // tab_size passed for format printing E->setnPubRO(nb_diff_ML); E->setnPubWO(nb_diff_ML); E->setnPrivate(nb_diff_ML); E->setnPrivROWO(); for (int i = 0; i < nb_threads; i++) { threads[i] = new TestThread(nb_diff_ML, nb_diff_CL, nb_max_trans, nb_max_insts, line_size, cache_lines, E, i); } } ~Program() { for (int i = 0; i < nb_threads; i++) { delete threads[i]; } delete [] threads; delete E; } string writeOutput() { stringstream res; res << endl; res << "#include " << endl; res << "#include " << endl; res << "#include " << endl; res << endl; res << "#ifdef _ALMOS_" << endl; res << "#define rd_wr_unc(index) ({ \\" << endl; res << " asm volatile( \\" << endl; res << " \"li $8, \" #index \"\\n\" \\" << endl; res << " \"sll $8, $8, 2\\n\" \\" << endl; res << " \"addu $8, $8, %0\\n\" \\" << endl; res << " \"li $10, 0xC\\n\" \\" << endl; //res << " \"mtc2 $10, $1\\n\" \\" << endl; res << " \"lw $9, 0($8)\\n\" \\" << endl; res << " \"add $9, $9, 1\\n\" \\" << endl; res << " \"sw $9, 0($8)\\n\" \\"<< endl; res << " \"li $10, 0xF\\n\" \\" << endl; //res << " \"mtc2 $10, $1\\n\" \\" << endl; res << " : \\" << endl; res << " : \"r\" (tab) \\" << endl; res << " : \"$8\", \"$9\", \"$10\"); \\" << endl; res << "})" << endl; res << endl; res << "#define wr_unc(index) ({ \\" << endl; res << " asm volatile( \\" << endl; res << " \"li $8, \" #index \"\\n\" \\" << endl; res << " \"sll $8, $8, 2\\n\" \\" << endl; res << " \"addu $8, $8, %0\\n\" \\" << endl; res << " \"li $10, 0xC\\n\" \\" << endl; //res << " \"mtc2 $10, $1\\n\" \\" << endl; res << " \"sw $0, 0($8)\\n\" \\"<< endl; res << " \"li $10, 0xF\\n\" \\" << endl; //res << " \"mtc2 $10, $1\\n\" \\" << endl; res << " : \\" << endl; res << " : \"r\" (tab) \\" << endl; res << " : \"$8\", \"$10\"); \\" << endl; res << "})" << endl; res << endl; res << "#define rd_unc(index) ({ \\" << endl; res << " asm volatile( \\" << endl; res << " \"li $8, \" #index \"\\n\" \\" << endl; res << " \"sll $8, $8, 2\\n\" \\" << endl; res << " \"addu $8, $8, %0\\n\" \\" << endl; res << " \"li $10, 0xC\\n\" \\" << endl; //res << " \"mtc2 $10, $1\\n\" \\" << endl; res << " \"lw $9, 0($8)\\n\" \\" << endl; res << " \"li $10, 0xF\\n\" \\" << endl; //res << " \"mtc2 $10, $1\\n\" \\" << endl; res << " : \\" << endl; res << " : \"r\" (tab) \\" << endl; res << " : \"$8\", \"$9\", \"$10\"); \\" << endl; res << "})" << endl; res << endl; res << "#else" << endl; res << " #define rd_wr_unc(index) ({ tab[index]++; })" << endl; res << " #define rd_unc(index) ({ local_var = tab[index]; })" << endl; res << " #define wr_unc(index) ({ tab[index] = 0; })" << endl; res << "#endif" << endl; res << endl; res << "#define NB_THREADS " << nb_threads << endl; res << endl; res << "/* NB_MAX_TRANS : " << NB_MAX_TRANS << endl; res << " * NB_MAX_INSTS : " << NB_MAX_INSTS << endl; res << " * LINE_SIZE : " << LINE_SIZE << endl; res << " * CACHE_LINES : " << CACHE_LINES << endl; res << " */" << endl; res << endl; res << "volatile int tab[" << tab_size << "];" << endl; res << endl; res << "pthread_spinlock_t lock_tab[" << nb_diff_ML * line_size << "];" << endl; res << endl; res << E->writeVariablesNature(); res << endl; res << endl; for (int i = 0; i < nb_threads; i++) { res << threads[i]->writeOutput(i); } res << "int main() {" << endl; res << endl; res << " unsigned int start;" << endl; res << " unsigned int end;" << endl; res << " unsigned int result;" << endl; res << " int i;" << endl; res << " void (*main_run) (); // fonction run du main" << endl; res << endl; res << " #ifdef _ALMOS_" << endl; res << " printf(\"\\n\");" << endl; res << " #endif" << endl; res << endl; res << " printf(\"dans le main\\n\");" << endl; res << endl; res << " for (i = 0; i < " << nb_diff_ML * line_size << "; i++) {" << endl; res << " pthread_spin_init(&lock_tab[i], 0);" << endl; res << " }" << endl; res << " pthread_t** threads;" << endl; res << " threads = malloc(sizeof(pthread_t *) * NB_THREADS);" << endl; res << endl; res << " pthread_attr_t* attr;" << endl; res << " attr = malloc(sizeof(pthread_attr_t) * NB_THREADS);" << endl; res << endl; res << " int my_cpu;" << endl; res << " #ifdef _ALMOS_" << endl; res << " pthread_attr_getcpuid_np(&my_cpu);" << endl; res << " #else" << endl; res << " my_cpu = NB_THREADS - 1;" << endl; res << " #endif" << endl; res << " for (i = 0; i < NB_THREADS; i++) {" << endl; res << " if (i != my_cpu) { " << endl; res << " threads[i] = malloc(sizeof(pthread_t));" << endl; res << " pthread_attr_init(&attr[i]);" << endl; res << " #ifdef _ALMOS_" << endl; res << " pthread_attr_setcpuid_np(&attr[i], i, NULL);" << endl; res << " #endif" << endl; res << " } " << endl; res << " }" << endl; res << endl; int index; for (int i = 0; i < nb_diff_ML * line_size; i++) { index = index2realindex(i,nb_diff_CL,cache_lines,line_size); res << " tab[" << index << "] = " << index << ";" << endl; } res << endl; for (int i = 0; i < nb_threads; i++) { res << " run" << i << "();" << endl; } res << endl; for (int i = 0; i < nb_diff_ML * line_size; i++) { index = index2realindex(i,nb_diff_CL,cache_lines,line_size); res << " tab[" << index << "] = " << index << ";" << endl; } //res << " printf("%s --> create run\n",__func__);" << endl; //res << " start = GetTimeUS();" << endl; res << endl; res << " for (i = 0; i < NB_THREADS; i++) {" << endl; res << " if (i == 0) {" << endl; res << " if (i != my_cpu) { " << endl; res << " int error = pthread_create(threads[i], &attr[i], (void *) run0, 0);" << endl; res << " if (error != 0) {" << endl; res << " printf(\"*** Error in pthread_create\\n\");" << endl; res << " }" << endl; res << " }" << endl; res << " else {" << endl; res << " main_run = run0;" << endl; res << " }" << endl; res << " }" << endl; for (int i = 1; i < nb_threads; i++) { res << " else if (i == " << i << ") {" << endl; res << " if (i != my_cpu) { " << endl; res << " int error = pthread_create(threads[i], &attr[i], (void *) run" << i << ", 0);" << endl; res << " if (error != 0) {" << endl; res << " printf(\"*** Error in pthread_create\\n\");" << endl; res << " }" << endl; res << " }" << endl; res << " else {" << endl; res << " main_run = run" << i << ";" << endl; res << " }" << endl; res << " }" << endl; } res << " else {" << endl; res << " printf(\"Erreur : pas de fonction run correspondant au threads/processeur %d\\n\",i);" << endl; res << " }" << endl; res << " }" << endl; res << endl; res << " main_run();" << endl; res << endl; res << " for (i = 0; i < NB_THREADS; i++) {" << endl; res << " if (i != my_cpu) {" << endl; res << " pthread_join(*threads[i], NULL);" << endl; res << " }" << endl; res << " }" << endl; res << endl; //res << " end = GetTimeUS();" << endl; //res << " printf("%s <-- join run\n",__func__);" << endl; res << endl; res << " result = end - start;" << endl; //res << " printf(\"temps ecoule : %u\n\",result);" << endl; for (int i = 0; i < nb_diff_ML*line_size; i++) { index = index2realindex(i,nb_diff_CL,cache_lines,line_size); res << " printf(\"tab[" << index << "] final : %d\\n\",tab[" << index << "]);" << endl; } res << " #ifdef _ALMOS_" << endl; res << " *(int *) 0x0 = 0xDEADDEAD;" << endl; res << " #endif" << endl; res << endl; res << " return 0;" << endl; res << "} " << endl; return res.str(); } }; #endif