Cerium による並列処理向け I/O の設計と実装
Masataka Kohagura 27th, February
担当教官 : 河野 真治
当研究室ではCellおよびLinux、 Mac OS X上で動く並列プログラミングフレームワーク、 Ceriumの開発・改良を行っている
本研究では
I/0 を含む Task の動作改善を行った
|
I/O 専用の Thread を用意することにより、読み込みに専念させることができる
|
read mode | CPU num | ave time(s) |
mmap | 2 | 106.2 |
mmap | 12 | 154.6 |
一括Read | 12 | 114.9 |
Blocked Read(SPE_ANY) | 12 | 106.0 |
Blocked Read(IO_0) | (I/0) 1 + (Task) 11 | 99.2 |
(例題) multiply : 2つの数を掛け算するプログラム
float* A, B, C; // Task の宣言 HTaskPtr multiply = manager->create_task(MULTIPLY_TASK); // Task を実行する デバイスの設定 multiply->set_cpu(SPE_ANY); // Task に入力データのアドレスを追加 multiply->set_inData(0, (memaddr)A, sizeof(float)*length); multiply->set_inData(1, (memaddr)B, sizeof(float)*length); // Task に出力データのアドレスを追加 multiply->set_outData(0, (memaddr)C, sizeof(float)*length); // Task へ値を1つだけ渡す multiply->set_param(0,length); // Task を TaskList に set する multiply->spawn();
static int multiply(SchedTask *s,void *rbuf, void *wbuf) { float *A,*B,*C // 登録した inData を取得 A = (float*)s->get_input(rbuf,0); B = (float*)s->get_input(rbuf,1); // 登録した outData を取得 C = (float*)s->get_output(wbuf,0); // 登録した param を取得 long length=(long)s->get_param(0); for (int i=0;i < length;i++) { C[i] = A[i] * B[i]; } return 0; }
mmap(SchedTask *s, void *in, void *out) { // FileReadPtr : File情報などを格納している構造体 FileReadPtr fr = (FileReadPtr)in; int map = MAP_PRIVATE; fr->read_text = (char*)mmap(NULL,fr->filesize,PROT_READ,map,fr->fd,(off_t)0); }
HTaskPtr t_read = manager->create_task(READ_TASK); t_read->set_cpu(read_spe_cpu); // 読み出すファイルの格納場所を設定 t_read->set_outData(0, w->file_mmap + w->task_spawned * w->division_size, w->task_blocks * w->division_size); // ファイルディスクリプタの受け渡し t_read->set_param(0,w->fd); // ファイル読み込みの始点 t_read->set_param(1,w->task_spawned*w->division_size); // run_tasks(manager,w, w->task_blocks, t_read, t_next, w->division_size + w->extra_len); // ここで、ファイルに対して何らかの計算を掛けるような Task を設定する run_tasks(manager,w, w->task_blocks,・・・ ); // ファイル読み込みの終点 t_read->set_param(2,w->task_spawned*w->division_size + w->extra_len); t_read->spawn();
static int read_task(SchedTask *s, void *rbuf, void *wbuf) { long fd = (long)s->get_param(0); long start_read_position = (long)s->get_param(1); long end_read_position = (long)s->get_param(2); char *read_text = (char*)s->get_output(wbuf,0); long read_size = end_read_position - start_read_position; pread(fd, read_text, read_size , start_read_position); return 0; }