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 | |
---|