Cerium Task Manager
による正規表現の実装
Masataka Kohagura
10th December , 2013
Masataka Kohagura
10th December , 2013
マルチコア CPU を最大限に活かすためには、並列プログラミングによる並列度を向上させなければならないが、実装が難しい。 当研究室では Cerium Libraryを提供することによって並列プログラミングを容易にしているが、ファイル読み込み等のI/O部分に関してはまだ実装されていない。
本研究ではその例題として正規表現を実装し、I/Oの順次読み込みとTaskの並列化の設計・実装によって既存の正規表現の処理速度、処理効率を上げる。
変更前
int *fd = (int *)s->get_input(rbuf,0); ///ファイルディスクリプタの受取 long readsize = (long)s->get_param(0); long task_number = (long)s->get_param(1); char text[(long)readsize]; read(*fd,text,(long)readsize); s->printf("[start task No. %d]\n",task_number); s->printf("%s\n",text);
変更後
pread(*fd, text, (long)read_size , division_size*task_number);
read(int fd, void *buf, size_t count);
pread(int fd, void *buf, size_t count, off_t offset);
read関数だと、Taskの起動する順番やタイミングによって同じ場所を読み込んだりしてしまう。read関数は読み込んだ後にファイルディスクリプタをずらしてしまうので、そのような現象が起こると考えられる。
pread関数だと、ファイルディスクリプタを動かさずにoffsetを取ることで読み込む場所が替えることができる。これだと、上記の現象が起こらずにすむ。
% ./fileread -file d.txt filesize : 16398 one_task_size: 16384 task_num : 2 [start task No. 0] firstaaaaaaaaaaaaaaaaaaaaaa...16380 doin [start task No. 1] firstaaaaaaaaa
[start task No. 0] gxbaaabaaabab [start task No. 1] gxbaaabaaabab
変更前
run_start(TaskManager *manager,char *filename) { HTask *read; int *fd = (int*)manager->allocate(sizeof(int)); if ((*fd=open(filename,O_RDONLY,0666))==0) { fprintf(stderr,"can't open %s\n",filename); } ... for(int task_number = 0; task_number < task_num; task_number++){ read = manager->create_task(READ_TASK); read->set_cpu(spe_cpu); [task settings(省略)] } }
変更後
run_start(TaskManager *manager,char *filename) { int *fd = (int*)manager->allocate(sizeof(int)); 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); } ... FilereadPtr fr = (FilereadPtr)manager->allocate(sizeof(Fileread)); HTaskPtr run = manager->create_task(RUN_BLOCKS, (memaddr)&fr->self, sizeof(memaddr),0,0); run->spawn(); }
RUN_BLOCKS
SchedDefineTask1(RUN_BLOCKS,run16); run16(SchedTask *manager, void *in, void *out) { FilereadPtr fr = (FilereadPtr)in; HTaskPtr wait; for (int i = 0; (fr->left_size > 0) && (i < fr->task_blocks); i++) { HTaskPtr read = manager->create_task(Read_task); read->set_cpu(fr->cpu); if (i == fr->task_blocks / 2) wait = read; [task settings(省略)] } return 0; }
word countでの実装
filereadでの実装