Mercurial > hg > Members > kono > Cerium
view example/word_count/main.cc @ 742:4c2e6493b008
continue..
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 12 Jan 2010 10:22:45 +0900 |
parents | a969d3cdd20a |
children | fc9c3b23d875 |
line wrap: on
line source
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/mman.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include "TaskManager.h" #include "Func.h" extern void task_init(); const char *usr_help_str = "Usage: ./word_count [-cpu spe_num] [-file filename]\n"; typedef struct { caddr_t file_mmap; off_t size; } st_mmap_t; /*与えられたsizeをfix_byte_sizeの倍数にする(丸め込むっていうのかな?)*/ int fix_byte(int size,int fix_byte_size) { size = (size/fix_byte_size)*fix_byte_size + ((size%fix_byte_size)!= 0)*fix_byte_size; return size; } st_mmap_t my_mmap(char *filename) { /*マッピングだよ!*/ int fd = -1; int map = MAP_PRIVATE; st_mmap_t st_mmap; struct stat sb; if ((fd=open(filename,O_RDONLY,0666))==0) { fprintf(stderr,"can't open %s\n",filename); } if (fstat(fd,&sb)) { fprintf(stderr,"can't fstat %s\n",filename); } printf("file size %d\n",(int)sb.st_size); /*sizeをページングサイズの倍数にあわせる*/ st_mmap.size = fix_byte(sb.st_size,4096); printf("fix 4096byte file size %d\n",(int)st_mmap.size); st_mmap.file_mmap = (char*)mmap(NULL,st_mmap.size,PROT_READ,map,fd,(off_t)0); if (st_mmap.file_mmap == (caddr_t)-1) { fprintf(stderr,"Can't mmap file\n"); perror(NULL); exit(0); } return st_mmap; } void run_start(TaskManager *manager, char *filename) { HTaskPtr t_exec; HTaskPtr t_print; st_mmap_t st_mmap; st_mmap = my_mmap(filename); /*sizeはdivision_sizeの倍数にしている。*/ int size = st_mmap.size; char *file_mmap = st_mmap.file_mmap; /* 1task分のデータサイズ(byte) */ int division_size; if (size >= 4096*4) { division_size = 4096 * 4;/*16kbyte*/ } else { division_size = size; } printf("dvision_size %d\n",division_size); /* "word num" and "line num" */ int status_num = 2; /* taskの数 */ int task_num = size / division_size; int out_task_num = task_num + (division_size*task_num < size); printf("task_num %d\n",task_num); /* out用のdivision_size. statusが2つなので、あわせて16byteになるように、long long(8byte)を使用 */ int division_out_size = 16; /* out用のデータのサイズ。*/ int out_size = division_out_size*out_task_num; unsigned long long *o_data = (unsigned long long*)manager->allocate(out_size); printf("out size %d\n",out_size); /*各SPEの結果を合計して出力するタスク*/ t_print = manager->create_task(TASK_PRINT); t_print->add_inData(o_data, out_size); t_print->add_param(out_task_num); t_print->add_param(status_num); /*各SPEに処理するデータを割り振る。*/ /*渡すデータの最後が文字かどうか。(スペース、改行以外)*/ int word_flag = 0; int i; int task_size = 32; for (i = 0; i < task_num; i+=task_size) { HTask *task_main = manager->create_task_array(TASK_EXEC,task_size,2,1,1); int j ; Task *t_exec = 0; for(j = 0; j < task_size; j++) { t_exec = task_main->next_task_array(TASK_EXEC,t_exec); task_main->set_cpu(SPE_ANY); t_print->wait_for(task_main); // t_exec = manager->create_task(TASK_EXEC); t_exec->set_param(0,division_size); t_exec->set_param(1,word_flag); t_exec->set_inData(0,file_mmap + i*division_size, division_size); t_exec->set_outData(0,o_data + i*status_num, division_out_size); word_flag = ((file_mmap[(i+1)*division_size-1] != 0x20) && (file_mmap[(i+1)*division_size-1] != 0x0A)); size -= division_size; } task_main->spawn_task_array(t_exec->next()); } while (size>0) { t_exec = manager->create_task(TASK_EXEC); t_exec->set_param(0,size); t_exec->set_param(1,word_flag); t_exec->set_inData(0,file_mmap + i*division_size, size); t_exec->set_outData(0,o_data + i*status_num, division_out_size); t_exec->set_cpu(SPE_ANY); t_print->wait_for(t_exec); t_exec->spawn(); i++; size -= division_size; } t_print->spawn(); } char* init(int argc, char **argv) { char *filename = 0; for (int i = 1; argv[i]; ++i) { if (strcmp(argv[i], "-file") == 0) { filename = argv[i+1]; } } if (filename==0) { printf("usage: %s [-count 10] -file filename\n",argv[0]); exit(1); } return filename; } int TMmain(TaskManager *manager, int argc, char *argv[]) { char *filename = 0; filename = init(argc, argv); if (filename < 0) { return -1; } task_init(); run_start(manager, filename); return 0; }