Mercurial > hg > Game > Cerium
annotate example/regex_mas/main.cc @ 1634:c0841aa109a8 draft
add number of match position.
author | Masa <e085726@ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 11 Jun 2013 17:30:40 +0900 |
parents | d2581892b8ad |
children | aa967337bda2 |
rev | line source |
---|---|
1598 | 1 #include <stdio.h> |
2 #include <stdlib.h> | |
3 #include <string.h> | |
4 #include <sys/mman.h> | |
5 #include <sys/types.h> | |
6 #include <sys/stat.h> | |
7 #include <fcntl.h> | |
8 #include <unistd.h> | |
9 #include <sys/time.h> | |
10 #include "TaskManager.h" | |
11 #include "SchedTask.h" | |
12 #include "Func.h" | |
13 #include "WordCount.h" | |
14 | |
1630 | 15 #define EXTRA_LENGTH 3 |
16 | |
1598 | 17 /* ;TODO |
18 * PS3でCPU数が2以上の時に、あまりが計算されてない | |
19 */ | |
20 | |
21 extern void task_init(); | |
22 void TMend(TaskManager *); | |
1600
e63ce6aee28e
eraser word_count's tarces in regex_mas
Masa <e085726@ie.u-ryukyu.ac.jp>
parents:
1598
diff
changeset
|
23 //static double st_time; |
e63ce6aee28e
eraser word_count's tarces in regex_mas
Masa <e085726@ie.u-ryukyu.ac.jp>
parents:
1598
diff
changeset
|
24 //static double ed_time; |
1598 | 25 int all = 0; |
26 int use_task_array = 1; | |
27 int use_task_creater = 0; | |
28 int use_compat = 0; | |
29 int array_task_num = 8; | |
30 int spe_num = 1; | |
31 CPU_TYPE spe_cpu = SPE_ANY; | |
32 const char *usr_help_str = "Usage: ./word_count [-a -c -s] [-cpu spe_num] [-file filename]\n"; | |
33 | |
1600
e63ce6aee28e
eraser word_count's tarces in regex_mas
Masa <e085726@ie.u-ryukyu.ac.jp>
parents:
1598
diff
changeset
|
34 //static double |
e63ce6aee28e
eraser word_count's tarces in regex_mas
Masa <e085726@ie.u-ryukyu.ac.jp>
parents:
1598
diff
changeset
|
35 //getTime() { |
e63ce6aee28e
eraser word_count's tarces in regex_mas
Masa <e085726@ie.u-ryukyu.ac.jp>
parents:
1598
diff
changeset
|
36 // struct timeval tv; |
e63ce6aee28e
eraser word_count's tarces in regex_mas
Masa <e085726@ie.u-ryukyu.ac.jp>
parents:
1598
diff
changeset
|
37 // gettimeofday(&tv, NULL); |
e63ce6aee28e
eraser word_count's tarces in regex_mas
Masa <e085726@ie.u-ryukyu.ac.jp>
parents:
1598
diff
changeset
|
38 // return tv.tv_sec + (double)tv.tv_usec*1e-6; |
e63ce6aee28e
eraser word_count's tarces in regex_mas
Masa <e085726@ie.u-ryukyu.ac.jp>
parents:
1598
diff
changeset
|
39 //} |
1598 | 40 |
41 typedef struct { | |
42 caddr_t file_mmap; | |
43 off_t size; | |
44 } st_mmap_t; | |
45 | |
46 static void simple_task_creater(int in_total_size, int out_total_size, | |
47 int command, int in_data_size, int out_data_size, | |
48 void *in_data, void *out_data, SchedTask *manager, | |
49 HTask *wait_i, HTask *wait_me) { | |
50 int in_task_size = 0; | |
51 int out_task_size = 0; | |
52 | |
53 if (in_total_size != 0) { | |
54 in_task_size = in_total_size / in_data_size; | |
55 if (in_total_size != in_task_size * in_data_size) { | |
56 printf("mismatch of in_total_size and in_data_size\n"); | |
57 } | |
58 } | |
59 | |
60 if (out_total_size != 0) { | |
61 out_task_size = out_total_size / out_data_size; | |
62 if (out_total_size != out_task_size * out_data_size) { | |
63 printf("mismatch of out_total_size and out_data_size\n"); | |
64 } | |
65 } | |
66 | |
67 /*in, out の大きい方に合わせるのがいいかな? Taskの数は1Task分に使うデータの大きいほうを取るような仕様がいいかな*/ | |
68 int task_num = (in_task_size > out_task_size) ? in_task_size : out_task_size; | |
69 | |
70 if (task_num == 0) task_num = 1; | |
71 | |
72 /*spe分あればいいのかな?*/ | |
73 | |
74 int array_num = spe_num; | |
75 if (task_num < array_num) { | |
76 array_num = task_num; | |
77 } | |
78 | |
79 | |
80 HTaskPtr *task_array = (HTask**)manager->allocate(sizeof(HTask*)*array_num); | |
81 TaskPtr *t_exec = (Task**)manager->allocate(sizeof(Task*)*array_num); | |
82 | |
83 int array_length = task_num / array_num; | |
84 int rest = task_num % array_num; | |
85 | |
86 int index = 0; | |
87 | |
88 for (int k = 0; k < array_num; k++) { | |
89 | |
90 task_array[k] = manager->create_task_array(command,array_length,0,1,1); | |
91 t_exec[k] = 0; | |
92 | |
93 if (wait_me != 0) { | |
94 wait_me->wait_for(task_array[k]); | |
95 } | |
96 if (wait_i != 0) { | |
97 task_array[k]->wait_for(wait_i); | |
98 } | |
99 | |
100 } | |
101 | |
102 int length = in_data_size/sizeof(char); | |
103 for (int j = 0; j < array_length; j++) { | |
104 for (int k = 0; k < array_num; k++) { | |
105 | |
106 t_exec[k] = task_array[k]->next_task_array(command,t_exec[k]); | |
107 t_exec[k]->set_param(0,(memaddr)length); | |
108 t_exec[k]->set_inData(0,(char*)in_data + index*in_data_size, in_data_size); | |
109 t_exec[k]->set_outData(0,(char*)out_data + index*out_data_size, out_data_size); | |
110 index++; | |
111 | |
112 } | |
113 } | |
114 | |
115 for (int k = 0; k < array_num; k++) { | |
116 task_array[k]->spawn_task_array(t_exec[k]->next()); | |
117 task_array[k]->set_cpu(spe_cpu); | |
118 task_array[k]->spawn(); | |
119 } | |
120 | |
121 for (int k = 0; k < rest; k++) { | |
122 HTaskPtr t_exec = manager->create_task(command); | |
123 t_exec->set_param(0,(memaddr)length); | |
1610 | 124 int offset = length*k; |
125 t_exec->set_param(1,(memaddr)offset); | |
1598 | 126 t_exec->set_inData(0,(char*)in_data + index*in_data_size, in_data_size); |
127 t_exec->set_outData(0,(char*)out_data + index*out_data_size, out_data_size); | |
128 | |
129 index++; | |
130 | |
131 if (wait_me != 0) { | |
132 wait_me->wait_for(t_exec); | |
133 } | |
134 if (wait_i != 0) { | |
135 t_exec->wait_for(wait_i); | |
136 } | |
137 | |
138 t_exec->set_cpu(spe_cpu); | |
139 t_exec->spawn(); | |
140 | |
141 } | |
142 | |
143 | |
144 } | |
145 | |
146 | |
147 /*与えられたsizeをfix_byte_sizeの倍数にする(丸め込むっていうのかな?)*/ | |
148 static int | |
149 fix_byte(int size,int fix_byte_size) | |
150 { | |
151 size = (size/fix_byte_size)*fix_byte_size + ((size%fix_byte_size)!= 0)*fix_byte_size; | |
152 | |
153 return size; | |
154 } | |
155 | |
156 | |
157 static st_mmap_t | |
158 my_mmap(char *filename) | |
159 { | |
160 | |
161 /*マッピングだよ!*/ | |
162 int fd = -1; | |
163 int map = MAP_PRIVATE; | |
164 st_mmap_t st_mmap; | |
165 struct stat sb; | |
166 | |
167 if ((fd=open(filename,O_RDONLY,0666))==0) { | |
168 fprintf(stderr,"can't open %s\n",filename); | |
169 } | |
170 | |
171 if (fstat(fd,&sb)) { | |
172 fprintf(stderr,"can't fstat %s\n",filename); | |
173 } | |
174 | |
175 /*sizeをページングサイズの倍数にあわせる*/ | |
1630 | 176 st_mmap.size = fix_byte(sb.st_size,4096 + EXTRA_LENGTH); //セグフォ防止 |
1598 | 177 |
178 st_mmap.file_mmap = (char*)mmap(NULL,st_mmap.size,PROT_READ,map,fd,(off_t)0); | |
179 if (st_mmap.file_mmap == (caddr_t)-1) { | |
180 fprintf(stderr,"Can't mmap file\n"); | |
181 perror(NULL); | |
182 exit(0); | |
183 } | |
184 | |
185 return st_mmap; | |
186 | |
187 } | |
188 | |
189 static void | |
190 run_tasks(SchedTask *manager, WordCount *w, int task_count, HTaskPtr t_next, int size) | |
191 { | |
192 | |
193 if (task_count < array_task_num) { | |
194 array_task_num = task_count; | |
195 if (task_count<=0) return; | |
196 } | |
197 | |
198 if (use_task_creater) { | |
199 simple_task_creater(w->file_size, w->division_out_size * w->task_num, TASK_EXEC, w->division_size, w->division_out_size, | |
200 w->file_mmap, w->o_data, manager, w->t_print, 0); | |
201 } | |
202 | |
203 if (use_task_array) { | |
204 | |
205 int spl = spe_num * array_task_num; | |
206 int loop = (task_count + spl - 1) / spl; | |
207 | |
208 for (int i = 0; i < loop; i += 1) { | |
209 | |
210 if (spl > w->task_num) { | |
211 if (w->task_num >= spe_num) { | |
212 array_task_num = w->task_num / spe_num; | |
213 } else { | |
214 | |
215 int task_num = w->task_num; | |
216 | |
217 for (int j = 0; j < task_num; j++) { | |
218 HTask *h_exec = 0; | |
219 int i = w->task_spwaned++; | |
220 | |
221 if (w->size < size) size = w->size; | |
222 | |
223 h_exec = manager->create_task(TASK_EXEC, | |
224 (memaddr)(w->file_mmap + i*w->division_size), size, | |
225 (memaddr)(w->o_data + i*w->out_size), w->division_out_size); | |
226 | |
227 if (all) { | |
228 w->t_print->wait_for(h_exec); | |
229 } else { | |
230 t_next->wait_for(h_exec); | |
231 } | |
232 | |
233 h_exec->set_cpu(spe_cpu); | |
234 h_exec->spawn(); | |
235 | |
236 w->size -= size; | |
237 if (w->size == 0) break; | |
238 w->task_num--; | |
239 | |
240 } | |
241 | |
242 return; | |
243 } | |
244 } | |
245 | |
246 // ここから | |
247 HTask **task_array = (HTask**)manager->allocate(sizeof(HTask*)*spe_num); | |
248 Task **t_exec = (Task**)manager->allocate(sizeof(Task*)*spe_num); | |
249 | |
250 for (int k = 0; k < spe_num; k++) { | |
251 task_array[k] = manager->create_task_array(TASK_EXEC,array_task_num,1,1,1); | |
252 t_exec[k] = 0; | |
253 if (all) { | |
254 w->t_print->wait_for(task_array[k]); | |
255 } else { | |
256 t_next->wait_for(task_array[k]); | |
257 } | |
258 } | |
259 | |
260 for (int j = 0; j < array_task_num; j++) { | |
261 for (int k = 0; k < spe_num; k++) { | |
262 | |
263 int a = w->task_spwaned++; | |
264 | |
265 if (w->size < size) size = w->size; | |
266 int length = size/sizeof(char); | |
1634
c0841aa109a8
add number of match position.
Masa <e085726@ie.u-ryukyu.ac.jp>
parents:
1630
diff
changeset
|
267 const int ONE_TASK_LENGTH = w->division_size; |
1598 | 268 |
269 t_exec[k] = task_array[k]->next_task_array(TASK_EXEC,t_exec[k]); | |
1634
c0841aa109a8
add number of match position.
Masa <e085726@ie.u-ryukyu.ac.jp>
parents:
1630
diff
changeset
|
270 t_exec[k]->set_param(0,(memaddr)length); |
c0841aa109a8
add number of match position.
Masa <e085726@ie.u-ryukyu.ac.jp>
parents:
1630
diff
changeset
|
271 const int ONE_LOOP_LENGTH = array_task_num*spe_num*ONE_TASK_LENGTH; |
c0841aa109a8
add number of match position.
Masa <e085726@ie.u-ryukyu.ac.jp>
parents:
1630
diff
changeset
|
272 const int ARRAY_LENGTH_SIZE = spe_num * ONE_TASK_LENGTH; |
c0841aa109a8
add number of match position.
Masa <e085726@ie.u-ryukyu.ac.jp>
parents:
1630
diff
changeset
|
273 int offset = ONE_LOOP_LENGTH * i + ARRAY_LENGTH_SIZE*j + ONE_TASK_LENGTH*k; |
c0841aa109a8
add number of match position.
Masa <e085726@ie.u-ryukyu.ac.jp>
parents:
1630
diff
changeset
|
274 t_exec[k]->set_param(1,(memaddr)offset); |
1630 | 275 t_exec[k]->set_inData(0,w->file_mmap + a*w->division_size, size + EXTRA_LENGTH); //それとも、ここで指定??ここっぽい |
1598 | 276 t_exec[k]->set_outData(0,w->o_data + a*w->out_size, w->division_out_size); |
277 | |
278 w->size -= size; | |
279 w->task_num--; | |
280 } | |
281 } | |
282 for (int k = 0; k < spe_num; k++) { | |
283 task_array[k]->spawn_task_array(t_exec[k]->next()); | |
284 task_array[k]->set_cpu(spe_cpu); | |
285 task_array[k]->spawn(); | |
286 } | |
287 | |
288 } | |
289 | |
290 return; | |
291 | |
292 } | |
293 | |
294 for (int i = 0; i < task_count; i += array_task_num) { | |
295 | |
296 HTask *h_exec = 0; | |
297 for (int j = 0; j < array_task_num; j++) { | |
298 int i = w->task_spwaned++; | |
299 if (w->size < size) size = w->size; | |
300 int length = size/sizeof(char); | |
301 if (size==0) break; | |
302 | |
303 if (use_compat) { | |
304 h_exec = manager->create_task(TASK_EXEC); | |
305 h_exec->set_param(0,(memaddr)length); | |
306 h_exec->set_inData(0,w->file_mmap + i*w->division_size, size); | |
307 h_exec->set_outData(0,w->o_data + i*w->out_size, w->division_out_size); | |
308 | |
309 | |
310 if (all) { | |
311 w->t_print->wait_for(h_exec); | |
312 } else { | |
313 t_next->wait_for(h_exec); | |
314 } | |
315 | |
316 h_exec->set_cpu(spe_cpu); | |
317 h_exec->spawn(); | |
318 | |
319 } else { | |
320 h_exec = manager->create_task(TASK_EXEC, | |
321 (memaddr)(w->file_mmap + i*w->division_size), size, | |
322 (memaddr)(w->o_data + i*w->out_size), w->division_out_size); | |
323 | |
324 if (all) { | |
325 w->t_print->wait_for(h_exec); | |
326 } else { | |
327 t_next->wait_for(h_exec); | |
328 } | |
329 | |
330 h_exec->set_cpu(spe_cpu); | |
331 h_exec->spawn(); | |
332 } | |
333 w->size -= size; | |
334 w->task_num--; | |
335 } | |
336 | |
337 } | |
338 | |
339 } | |
340 | |
341 /** | |
342 * このTaskは、PPE上で実行されるので、並列に実行されることはない | |
343 * 二つ実行されていて、Task が足りなくなることがないようにしている。 | |
344 */ | |
345 | |
346 SchedDefineTask1(RUN_TASK_BLOCKS,run16); | |
347 | |
348 static int | |
349 run16(SchedTask *manager, void *in, void *out) | |
350 { | |
351 WordCount *w = *(WordCount **)in; | |
352 | |
353 if (w->task_num < w->task_blocks) { | |
354 // last case | |
355 while (w->size >= w->division_size) | |
356 run_tasks(manager,w,w->task_num, w->t_print, w->division_size); | |
357 // remaining data | |
358 while (w->size>0) | |
359 run_tasks(manager,w,1, w->t_print, w->size); | |
360 // printf("run16 last %d\n",w->task_num); | |
361 } else { | |
362 HTaskPtr t_next = manager->create_task(RUN_TASK_BLOCKS, | |
363 (memaddr)&w->self,sizeof(memaddr),0,0); | |
364 w->t_print->wait_for(t_next); | |
365 | |
366 run_tasks(manager,w, w->task_blocks, t_next, w->division_size); | |
367 | |
368 t_next->spawn(); | |
369 // printf("run16 next %d\n",w->task_num); | |
370 } | |
371 return 0; | |
372 } | |
373 | |
374 | |
375 static int blocks = 48; | |
376 //static int blocks = 31 * 6 * 24; | |
377 static int division = 16; // in Kbyte | |
378 | |
379 static void | |
380 run_start(TaskManager *manager, char *filename) | |
381 { | |
382 HTaskPtr t_print; | |
383 | |
384 st_mmap_t st_mmap; | |
385 st_mmap = my_mmap(filename); | |
386 WordCount *w = (WordCount*)manager->allocate(sizeof(WordCount)); | |
387 // bzero(w,sizeof(WordCount)); | |
388 | |
389 //w->task_blocks = blocks; | |
390 w->self = w; | |
391 w->task_spwaned = 0; | |
392 | |
393 /*sizeはdivision_sizeの倍数にしている。*/ | |
394 w->size = w->file_size = st_mmap.size; | |
395 w->file_mmap = st_mmap.file_mmap; | |
396 /* 1task分のデータサイズ(byte) */ | |
397 if (w->size >= 1024*division) { | |
398 w->division_size = 1024 * division;/*16kbyte*/ | |
399 } else { | |
400 w->division_size = w->size; | |
401 } | |
402 | |
403 /* "word num" and "line num" */ | |
404 w->status_num = 2; | |
405 /* taskの数 */ | |
406 w->task_num = w->size / w->division_size; | |
407 w->task_num = w->task_num + (w->division_size*w->task_num < w->size); | |
408 int out_task_num = w->task_num; | |
409 | |
410 if(!all) { | |
411 w->task_blocks = blocks; | |
412 } else { | |
413 w->task_blocks = w->task_num; | |
414 } | |
415 | |
416 w->out_task_num = out_task_num; | |
417 | |
418 /* out用のdivision_size. statusが2つなので、あわせて16byteになるように、long long(4byte)を使用 */ | |
419 | |
420 w->division_out_size = sizeof(unsigned long long)*4; | |
421 int out_size = w->division_out_size*out_task_num; | |
422 w->o_data = (unsigned long long *)manager->allocate(out_size); | |
423 w->out_size = 4; | |
424 | |
425 /*各SPEの結果を合計して出力するタスク*/ | |
426 | |
427 t_print = manager->create_task(TASK_PRINT, | |
428 (memaddr)&w->self,sizeof(memaddr),0,0); | |
429 w->t_print = t_print; | |
430 | |
431 for(int i = 0;i<20;i++) { | |
432 /* Task を task_blocks ずつ起動する Task */ | |
433 /* serialize されていると仮定する... */ | |
434 HTaskPtr t_exec = manager->create_task(RUN_TASK_BLOCKS, | |
435 (memaddr)&w->self,sizeof(memaddr),0,0); | |
436 t_print->wait_for(t_exec); | |
437 t_exec->spawn(); | |
438 } | |
439 | |
440 t_print->spawn(); | |
441 } | |
442 | |
443 static char* | |
444 init(int argc, char **argv) | |
445 { | |
446 | |
447 char *filename = 0; | |
448 | |
449 for (int i = 1; argv[i]; ++i) { | |
450 if (strcmp(argv[i], "-file") == 0) { | |
451 filename = argv[i+1]; | |
452 } else if (strcmp(argv[i], "-division") == 0) { | |
453 division = atoi(argv[i+1]); | |
454 } else if (strcmp(argv[i], "-block") == 0) { | |
455 blocks = atoi(argv[i+1]); | |
456 } else if (strcmp(argv[i], "-a") == 0) { | |
457 // create task all at once | |
458 all = 1; | |
459 } else if (strcmp(argv[i], "-c") == 0) { | |
460 use_task_array = 0; | |
461 use_compat = 1; | |
462 } else if (strcmp(argv[i], "-s") == 0) { | |
463 use_task_array = 0; | |
464 use_compat = 0; | |
465 } else if (strcmp(argv[i], "-t") == 0) { | |
466 use_task_creater = 1; | |
467 use_task_array = 0; | |
468 use_compat = 0; | |
469 } else if (strcmp(argv[i], "-anum") == 0) { | |
470 array_task_num = atoi(argv[i+1]); | |
471 } else if (strcmp(argv[i], "-g") == 0 ) { | |
472 spe_cpu = GPU_0; | |
473 } else if (strcmp(argv[i], "-cpu") == 0) { | |
474 spe_num = atoi(argv[i+1]); | |
475 if (spe_num==0) spe_num = 1; | |
476 } | |
477 } | |
478 if (filename==0) { | |
479 puts(usr_help_str); | |
480 exit(1); | |
481 } | |
482 | |
483 return filename; | |
484 } | |
485 | |
486 | |
487 int | |
488 TMmain(TaskManager *manager, int argc, char *argv[]) | |
489 { | |
490 | |
491 char *filename = 0; | |
492 filename = init(argc, argv); | |
493 | |
494 if (filename < 0) { | |
495 return -1; | |
496 } | |
497 | |
498 task_init(); | |
499 run_start(manager, filename); | |
500 return 0; | |
501 } | |
502 | |
503 /* end */ |