[843] | 1 | |
---|
| 2 | #ifndef _program_hpp_ |
---|
| 3 | #define _program_hpp_ |
---|
| 4 | |
---|
| 5 | #include "config.h" |
---|
| 6 | #include "TestThread.hpp" |
---|
| 7 | #include "EnsembleVariables.hpp" |
---|
| 8 | |
---|
| 9 | #include <iostream> |
---|
| 10 | #include <sstream> |
---|
| 11 | |
---|
| 12 | using namespace std; |
---|
| 13 | |
---|
| 14 | class Program { |
---|
| 15 | |
---|
| 16 | int nb_lines_uncached; |
---|
| 17 | int nb_threads; |
---|
| 18 | int tab_size; |
---|
| 19 | int nb_diff_ML, nb_diff_CL, line_size, cache_lines; |
---|
| 20 | EnsembleVariables * E; |
---|
| 21 | TestThread** threads; |
---|
| 22 | |
---|
| 23 | public: |
---|
| 24 | |
---|
| 25 | 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) { |
---|
| 26 | nb_lines_uncached = 1; |
---|
| 27 | nb_threads = nb_procs; |
---|
| 28 | threads = new TestThread*[nb_threads]; |
---|
| 29 | 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); |
---|
| 30 | this->nb_diff_ML = nb_diff_ML; |
---|
| 31 | this->nb_diff_CL = nb_diff_CL; |
---|
| 32 | this->line_size = line_size; |
---|
| 33 | this->cache_lines = cache_lines; |
---|
| 34 | |
---|
| 35 | 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 |
---|
| 36 | |
---|
| 37 | E->setnPubRO(nb_diff_ML); |
---|
| 38 | E->setnPubWO(nb_diff_ML); |
---|
| 39 | E->setnPrivate(nb_diff_ML); |
---|
| 40 | E->setnPrivROWO(); |
---|
| 41 | |
---|
| 42 | for (int i = 0; i < nb_threads; i++) { |
---|
| 43 | threads[i] = new TestThread(nb_diff_ML, nb_diff_CL, nb_max_trans, nb_max_insts, line_size, cache_lines, E, i); |
---|
| 44 | } |
---|
| 45 | } |
---|
| 46 | |
---|
| 47 | ~Program() { |
---|
| 48 | for (int i = 0; i < nb_threads; i++) { |
---|
| 49 | delete threads[i]; |
---|
| 50 | } |
---|
| 51 | delete [] threads; |
---|
| 52 | delete E; |
---|
| 53 | } |
---|
| 54 | |
---|
| 55 | string writeOutput() { |
---|
| 56 | stringstream res; |
---|
| 57 | res << endl; |
---|
| 58 | res << "#include <pthread.h>" << endl; |
---|
| 59 | res << "#include <stdlib.h>" << endl; |
---|
| 60 | res << "#include <stdio.h>" << endl; |
---|
| 61 | res << endl; |
---|
| 62 | |
---|
| 63 | res << "#ifdef _ALMOS_" << endl; |
---|
| 64 | res << "#define rd_wr_unc(index) ({ \\" << endl; |
---|
| 65 | res << " asm volatile( \\" << endl; |
---|
| 66 | res << " \"li $8, \" #index \"\\n\" \\" << endl; |
---|
| 67 | res << " \"sll $8, $8, 2\\n\" \\" << endl; |
---|
| 68 | res << " \"addu $8, $8, %0\\n\" \\" << endl; |
---|
| 69 | res << " \"li $10, 0xC\\n\" \\" << endl; |
---|
| 70 | //res << " \"mtc2 $10, $1\\n\" \\" << endl; |
---|
| 71 | res << " \"lw $9, 0($8)\\n\" \\" << endl; |
---|
| 72 | res << " \"add $9, $9, 1\\n\" \\" << endl; |
---|
| 73 | res << " \"sw $9, 0($8)\\n\" \\"<< endl; |
---|
| 74 | res << " \"li $10, 0xF\\n\" \\" << endl; |
---|
| 75 | //res << " \"mtc2 $10, $1\\n\" \\" << endl; |
---|
| 76 | res << " : \\" << endl; |
---|
| 77 | res << " : \"r\" (tab) \\" << endl; |
---|
| 78 | res << " : \"$8\", \"$9\", \"$10\"); \\" << endl; |
---|
| 79 | res << "})" << endl; |
---|
| 80 | res << endl; |
---|
| 81 | |
---|
| 82 | res << "#define wr_unc(index) ({ \\" << endl; |
---|
| 83 | res << " asm volatile( \\" << endl; |
---|
| 84 | res << " \"li $8, \" #index \"\\n\" \\" << endl; |
---|
| 85 | res << " \"sll $8, $8, 2\\n\" \\" << endl; |
---|
| 86 | res << " \"addu $8, $8, %0\\n\" \\" << endl; |
---|
| 87 | res << " \"li $10, 0xC\\n\" \\" << endl; |
---|
| 88 | //res << " \"mtc2 $10, $1\\n\" \\" << endl; |
---|
| 89 | res << " \"sw $0, 0($8)\\n\" \\"<< endl; |
---|
| 90 | res << " \"li $10, 0xF\\n\" \\" << endl; |
---|
| 91 | //res << " \"mtc2 $10, $1\\n\" \\" << endl; |
---|
| 92 | res << " : \\" << endl; |
---|
| 93 | res << " : \"r\" (tab) \\" << endl; |
---|
| 94 | res << " : \"$8\", \"$10\"); \\" << endl; |
---|
| 95 | res << "})" << endl; |
---|
| 96 | res << endl; |
---|
| 97 | |
---|
| 98 | res << "#define rd_unc(index) ({ \\" << endl; |
---|
| 99 | res << " asm volatile( \\" << endl; |
---|
| 100 | res << " \"li $8, \" #index \"\\n\" \\" << endl; |
---|
| 101 | res << " \"sll $8, $8, 2\\n\" \\" << endl; |
---|
| 102 | res << " \"addu $8, $8, %0\\n\" \\" << endl; |
---|
| 103 | res << " \"li $10, 0xC\\n\" \\" << endl; |
---|
| 104 | //res << " \"mtc2 $10, $1\\n\" \\" << endl; |
---|
| 105 | res << " \"lw $9, 0($8)\\n\" \\" << endl; |
---|
| 106 | res << " \"li $10, 0xF\\n\" \\" << endl; |
---|
| 107 | //res << " \"mtc2 $10, $1\\n\" \\" << endl; |
---|
| 108 | res << " : \\" << endl; |
---|
| 109 | res << " : \"r\" (tab) \\" << endl; |
---|
| 110 | res << " : \"$8\", \"$9\", \"$10\"); \\" << endl; |
---|
| 111 | res << "})" << endl; |
---|
| 112 | res << endl; |
---|
| 113 | res << "#else" << endl; |
---|
| 114 | res << " #define rd_wr_unc(index) ({ tab[index]++; })" << endl; |
---|
| 115 | res << " #define rd_unc(index) ({ local_var = tab[index]; })" << endl; |
---|
| 116 | res << " #define wr_unc(index) ({ tab[index] = 0; })" << endl; |
---|
| 117 | res << "#endif" << endl; |
---|
| 118 | |
---|
| 119 | res << endl; |
---|
| 120 | res << "#define NB_THREADS " << nb_threads << endl; |
---|
| 121 | res << endl; |
---|
| 122 | res << "/* NB_MAX_TRANS : " << NB_MAX_TRANS << endl; |
---|
| 123 | res << " * NB_MAX_INSTS : " << NB_MAX_INSTS << endl; |
---|
| 124 | res << " * LINE_SIZE : " << LINE_SIZE << endl; |
---|
| 125 | res << " * CACHE_LINES : " << CACHE_LINES << endl; |
---|
| 126 | res << " */" << endl; |
---|
| 127 | res << endl; |
---|
| 128 | res << "volatile int tab[" << tab_size << "];" << endl; |
---|
| 129 | res << endl; |
---|
| 130 | res << "pthread_spinlock_t lock_tab[" << nb_diff_ML * line_size << "];" << endl; |
---|
| 131 | res << endl; |
---|
| 132 | res << E->writeVariablesNature(); |
---|
| 133 | res << endl; |
---|
| 134 | res << endl; |
---|
| 135 | |
---|
| 136 | for (int i = 0; i < nb_threads; i++) { |
---|
| 137 | res << threads[i]->writeOutput(i); |
---|
| 138 | } |
---|
| 139 | |
---|
| 140 | res << "int main() {" << endl; |
---|
| 141 | res << endl; |
---|
| 142 | res << " unsigned int start;" << endl; |
---|
| 143 | res << " unsigned int end;" << endl; |
---|
| 144 | res << " unsigned int result;" << endl; |
---|
| 145 | res << " int i;" << endl; |
---|
| 146 | res << " void (*main_run) (); // fonction run du main" << endl; |
---|
| 147 | res << endl; |
---|
| 148 | res << " #ifdef _ALMOS_" << endl; |
---|
| 149 | res << " printf(\"\\n\");" << endl; |
---|
| 150 | res << " #endif" << endl; |
---|
| 151 | res << endl; |
---|
| 152 | res << " printf(\"dans le main\\n\");" << endl; |
---|
| 153 | res << endl; |
---|
| 154 | res << " for (i = 0; i < " << nb_diff_ML * line_size << "; i++) {" << endl; |
---|
| 155 | res << " pthread_spin_init(&lock_tab[i], 0);" << endl; |
---|
| 156 | res << " }" << endl; |
---|
| 157 | res << " pthread_t** threads;" << endl; |
---|
| 158 | res << " threads = malloc(sizeof(pthread_t *) * NB_THREADS);" << endl; |
---|
| 159 | res << endl; |
---|
| 160 | res << " pthread_attr_t* attr;" << endl; |
---|
| 161 | res << " attr = malloc(sizeof(pthread_attr_t) * NB_THREADS);" << endl; |
---|
| 162 | res << endl; |
---|
| 163 | res << " int my_cpu;" << endl; |
---|
| 164 | res << " #ifdef _ALMOS_" << endl; |
---|
| 165 | res << " pthread_attr_getcpuid_np(&my_cpu);" << endl; |
---|
| 166 | res << " #else" << endl; |
---|
| 167 | res << " my_cpu = NB_THREADS - 1;" << endl; |
---|
| 168 | res << " #endif" << endl; |
---|
| 169 | res << " for (i = 0; i < NB_THREADS; i++) {" << endl; |
---|
| 170 | res << " if (i != my_cpu) { " << endl; |
---|
| 171 | res << " threads[i] = malloc(sizeof(pthread_t));" << endl; |
---|
| 172 | res << " pthread_attr_init(&attr[i]);" << endl; |
---|
| 173 | res << " #ifdef _ALMOS_" << endl; |
---|
| 174 | res << " pthread_attr_setcpuid_np(&attr[i], i, NULL);" << endl; |
---|
| 175 | res << " #endif" << endl; |
---|
| 176 | res << " } " << endl; |
---|
| 177 | res << " }" << endl; |
---|
| 178 | res << endl; |
---|
| 179 | |
---|
| 180 | int index; |
---|
| 181 | for (int i = 0; i < nb_diff_ML * line_size; i++) { |
---|
| 182 | index = index2realindex(i,nb_diff_CL,cache_lines,line_size); |
---|
| 183 | res << " tab[" << index << "] = " << index << ";" << endl; |
---|
| 184 | } |
---|
| 185 | res << endl; |
---|
| 186 | for (int i = 0; i < nb_threads; i++) { |
---|
| 187 | res << " run" << i << "();" << endl; |
---|
| 188 | } |
---|
| 189 | res << endl; |
---|
| 190 | for (int i = 0; i < nb_diff_ML * line_size; i++) { |
---|
| 191 | index = index2realindex(i,nb_diff_CL,cache_lines,line_size); |
---|
| 192 | res << " tab[" << index << "] = " << index << ";" << endl; |
---|
| 193 | } |
---|
| 194 | |
---|
| 195 | //res << " printf("%s --> create run\n",__func__);" << endl; |
---|
| 196 | //res << " start = GetTimeUS();" << endl; |
---|
| 197 | res << endl; |
---|
| 198 | res << " for (i = 0; i < NB_THREADS; i++) {" << endl; |
---|
| 199 | res << " if (i == 0) {" << endl; |
---|
| 200 | res << " if (i != my_cpu) { " << endl; |
---|
| 201 | res << " int error = pthread_create(threads[i], &attr[i], (void *) run0, 0);" << endl; |
---|
| 202 | res << " if (error != 0) {" << endl; |
---|
| 203 | res << " printf(\"*** Error in pthread_create\\n\");" << endl; |
---|
| 204 | res << " }" << endl; |
---|
| 205 | res << " }" << endl; |
---|
| 206 | res << " else {" << endl; |
---|
| 207 | res << " main_run = run0;" << endl; |
---|
| 208 | res << " }" << endl; |
---|
| 209 | res << " }" << endl; |
---|
| 210 | for (int i = 1; i < nb_threads; i++) { |
---|
| 211 | res << " else if (i == " << i << ") {" << endl; |
---|
| 212 | res << " if (i != my_cpu) { " << endl; |
---|
| 213 | res << " int error = pthread_create(threads[i], &attr[i], (void *) run" << i << ", 0);" << endl; |
---|
| 214 | res << " if (error != 0) {" << endl; |
---|
| 215 | res << " printf(\"*** Error in pthread_create\\n\");" << endl; |
---|
| 216 | res << " }" << endl; |
---|
| 217 | res << " }" << endl; |
---|
| 218 | res << " else {" << endl; |
---|
| 219 | res << " main_run = run" << i << ";" << endl; |
---|
| 220 | res << " }" << endl; |
---|
| 221 | res << " }" << endl; |
---|
| 222 | } |
---|
| 223 | res << " else {" << endl; |
---|
| 224 | res << " printf(\"Erreur : pas de fonction run correspondant au threads/processeur %d\\n\",i);" << endl; |
---|
| 225 | res << " }" << endl; |
---|
| 226 | res << " }" << endl; |
---|
| 227 | res << endl; |
---|
| 228 | res << " main_run();" << endl; |
---|
| 229 | res << endl; |
---|
| 230 | res << " for (i = 0; i < NB_THREADS; i++) {" << endl; |
---|
| 231 | res << " if (i != my_cpu) {" << endl; |
---|
| 232 | res << " pthread_join(*threads[i], NULL);" << endl; |
---|
| 233 | res << " }" << endl; |
---|
| 234 | res << " }" << endl; |
---|
| 235 | res << endl; |
---|
| 236 | //res << " end = GetTimeUS();" << endl; |
---|
| 237 | //res << " printf("%s <-- join run\n",__func__);" << endl; |
---|
| 238 | res << endl; |
---|
| 239 | res << " result = end - start;" << endl; |
---|
| 240 | //res << " printf(\"temps ecoule : %u\n\",result);" << endl; |
---|
| 241 | |
---|
| 242 | for (int i = 0; i < nb_diff_ML*line_size; i++) { |
---|
| 243 | index = index2realindex(i,nb_diff_CL,cache_lines,line_size); |
---|
| 244 | res << " printf(\"tab[" << index << "] final : %d\\n\",tab[" << index << "]);" << endl; |
---|
| 245 | } |
---|
| 246 | res << " #ifdef _ALMOS_" << endl; |
---|
| 247 | res << " *(int *) 0x0 = 0xDEADDEAD;" << endl; |
---|
| 248 | res << " #endif" << endl; |
---|
| 249 | res << endl; |
---|
| 250 | res << " return 0;" << endl; |
---|
| 251 | res << "} " << endl; |
---|
| 252 | return res.str(); |
---|
| 253 | } |
---|
| 254 | |
---|
| 255 | }; |
---|
| 256 | |
---|
| 257 | #endif |
---|
| 258 | |
---|
| 259 | |
---|
| 260 | |
---|
| 261 | |
---|
| 262 | |
---|