Cerium による並列処理向け I/O の設計と実装
Masataka Kohagura 12th, February
担当教官 : 河野 真治
近年のCPUのほとんどはマルチコアであり、それらの性能を引き出すためには並列プログラミングが必須となっている。そこで当研究室では Cerium Library の開発を行い、提供することによって並列プログラミングを容易にしている。
先行研究では Task の並列化によって、プログラム全体の処理速度は向上しているが、ファイル読み込み等の I/O に対して並列に Task が動作するようにはされていない。
本研究では I/O と Task の並列化の設計、実装によってプログラム全体の処理速度、処理効率を上げていく。
|
// Task の宣言 HTaskPtr multiply = manager->create_task(MULTIPLY_TASK); // Task を実行する デバイスの設定 multiply->set_cpu(SPE_ANY); // Task に入力データのアドレスを追加 multiply->set_inData(0, i_data1, sizeof(float)*length); multiply->set_inData(1, i_data2, sizeof(float)*length); // Task に出力データのアドレスを追加 multiply->set_outData(0, o_data1, sizeof(float)*length); // Task へ値を1つだけ渡す multiply->set_param(0,(long)length); // Task を TaskList に set する multiply->spawn();
static int multiply(SchedTask *s,void *rbuf, void *wbuf) { // 登録した inData を取得 float indata1=(float*)s->get_input(rbuf,0); float indata2=(float*)s->get_input(rbuf,1); // 登録した outData を取得 float outdata=(float*)s->get_output(wbuf,0); // 登録した param を取得 long length=(long)s->get_param(0); for (int i=0;i < length;i++) { outdata[i]=indata1[i]*indata2[i]; } return 0; }
typedef struct fileRead { struct fileRead *self; long fd; long division_size; long file_size; ・・・ char *read_text; CPU_TYPE cpu; } FileRead, *FileReadPtr;
Fileを読み込む際にファイルの情報や、Read Task の情報を構造体の中に格納しておく。
mmap(SchedTask *s, void *in, void *out) { FileReadPtr fr = (FileReadPtr)in; int map = MAP_PRIVATE; fr->read_text = (char*)mmap(NULL,fr->filesize,PROT_READ,map,fr->fd,(off_t)0); }
// 生成するTaskが何番目か read->set_param(0,(long)w->read_task_number); // 1つの Read Task で読み込む量 read->set_param(1,(long)w->read_division_size); // read_left_size : 残り読み込み量 if(w->read_left_size <= w->read_division_size){ read->set_param(2,(long)w->read_left_size); }else{ read->set_param(2,(long)w->read_division_size); } // ファイルディスクリプタを渡す read->set_param(3,(long)w->fd); //生成するTaskが何番目か read->set_outData (0,w->file_mmap + w->read_task_number*w->read_division_size, w->read_division_size);
static int read_task(SchedTask *s, void *rbuf, void *wbuf) { long task_number = (long)s->get_param(0); long division_size = (long)s->get_param(1); long read_size = (long)s->get_param(2); long fd = (long)s->get_param(3); char *read_text = (char*)s->get_output(wbuf,0); pread(fd, read_text, (long)read_size , division_size*task_number); return 0; }