Mercurial > hg > Papers > 2014 > masakoha-sigos
view paper/cerium.tex @ 15:5bdd06f52b61
add expriment Data
author | Masataka Kohagura <e085726@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 21 Apr 2014 21:15:36 +0900 |
parents | 6f6f482b9f12 |
children | d354ebd64148 |
line wrap: on
line source
\section{Cerium TaskManager}\label{section:cerium} Cerium Task Manager は並列プログラミングフレームワークであり、内部では C や C++ で実装されている。 Cerium Task Manager は、User が並列処理を Task 単位で記述し、関数やサブルーチンを Task として扱い、その Task に対して Input Data、Output Data を設定する。 Input Data、Output Data とは関数でいう引数に相当する。そして Task が複数存在する場合、それらに依存関係を設定することができる。 そして、それに基づいた設定の元で Task Manager にて管理し実行される。 Cerium Task Manager は PlayStation 3/Cell、Mac OS X 及び Linux 上で利用することが可能である。 図\ref{fig:cerium} は Cerium が Task を作成・実行する場合のクラスの構成となる。User が createtask を行い、input data や Task の依存関係の設定を行うと、TaskManager で Task が生成される。 Task 毎に依存関係を表す wait\_i と wait\_me というリストがあり、依存関係が解消されて実行可能になった Task は ActiveTaskList に移される。さらに、Scheduler に転送する際には TaskList に変換を行ってから各 Scheduler に転送される。 \begin{figure}[htbp] \begin{center} \includegraphics[scale=0.3]{images/ceriumtaskmanager.pdf} \end{center} \caption{Cerium Task Manager} \label{fig:cerium} \end{figure} \newpage \subsection{Cerium Task Manager を使った例題} 今回計測に使用した例題 WordCount を例にとり、以下に Task の生成部分を以下に示す。 このプログラムは、WordCount Task と Print Task の2種類の Task から構成される。 input data とは、mmap や read で読み込んだファイルであり、このファイルを $ n $ KByte の大きさに分割して、WordCount Task にそれぞれ割り当てる。 WordCount Task は、input された data の単語数と行数をカウントし、それらを output に指定された data 領域に書きこむ。 以下に WordCount の Task 生成部分を示す。 \begin{verbatim} exec = manager->create_task(TASK_EXEC); exec->set_inData(0, file_mmap + i*division_size, size); exec->set_outData(0,o_data + i*out_size, division_out_size); exec->set_cpu(spe_cpu); exec->spawn(); i++; \end{verbatim} \begin{tiny} \begin{table}[ht] \begin{center} \label{table:create_taskAPI} \small \begin{tabular}[t]{c|l} \hline create\_task& Task を生成する \\ \hline set\_inData & Task に入力データのアドレスを追加 \\ \hline set\_outData & Task に出力データのアドレスを追加 \\ \hline set\_cpu & Task を実行するデバイスの設定 \\ \hline spawn & 生成した Task を TaskList に set \\ \hline \end{tabular} \caption{Task 生成における API} \end{center} \end{table} \end{tiny} set\_inData には、WordCount Task が担当するテキストの範囲を設定し、set\_outData にはその範囲の単語数や行数、範囲の先頭と末尾の状態を表すフラグを配列として格納してる。 input data は分割されたデータが送られてくるため、分割された前後のテキストがどうなっているかはわからない。 そのため、担当範囲であるデータの先頭と末尾のパラメータを単語数と行数の他に付け加える。後にそのデータを他の WordCount の結果と照らし合わせ、分割されたテキストを正しく整合する。 Task の記述は以下のようになる。 \\ \begin{verbatim} wordcount(SchedTask *s, void *rbuf, void *wbuf) { char *i_data = (char *)s->get_input(0); unsigned long long *o_data = (unsigned long long *)s->get_output(0); unsigned long long *head_tail_flag = o_data + 2; int length = (int)s->get_inputSize(0); head_tail_flag[0] = (i_data[0] != 0x20) && (i_data[0] != 0x0A); word_num -= 1-head_tail_flag[0]; for (; i < length; i++) { if (i_data[i] == 0x20) { word_flag = 1; } else if (i_data[i] == 0x0A) { line_num += 1; word_flag = 1; } else { word_num += word_flag; word_flag = 0; } } word_num += word_flag; head_tail_flag[1] = (i_data[i-1] != 0x20) && (i_data[i-1] != 0x0A); o_data[0] = (unsigned long long)word_num; o_data[1] = (unsigned long long)line_num; return 0; } \end{verbatim} \begin{tiny} \begin{table}[ht] \begin{center} \label{table:taskAPI} \small \begin{tabular}[t]{c|l} \hline get\_input & Scheduler から input data を取得 \\ \hline get\_output & Scheduler から output data を取得 \\ \hline get\_param & set\_param した値を取得 \\ \hline \end{tabular} \caption{Task 側で使用する API} \end{center} \end{table} \end{tiny} Print Task は WordCount Task によって書き出された単語数と行数を集計し、結果を出力する Task である。 WordCount Task が全て走り終わったあとに、Print Task が走るように依存関係を設定している。(図\ref{fig:wordcount}) \begin{figure}[htbp] \begin{center} \includegraphics[scale=0.4]{images/wordcount.pdf} \end{center} \caption{WordCount Model} \label{fig:wordcount} \end{figure} \if0 単語数や行数、そして担当範囲の先頭と末尾の文字列の状態を配列としてデータを保持している。 その配列を Print Task にて処理を行い単語数、行数を集計する。 しかし、分割のされ方によっては、単語数がカウントされない場合がある。(((図が必要!!!))) Print Task の記述は以下のようになる。 \begin{verbatim} static int run_print(SchedTask *s, void *rbuf, void *wbuf) { WordCount *w = (WordCount*)s->get_input(0); unsigned long long *idata = w->o_data; long status_num = w->status_num; int out_task_num = w->out_task_num; unsigned long long word_data[2]; int flag_cal_sum = 0; for (int i = 0; i < out_task_num ; i++) { word_data[0] += idata[i*w->out_size+0]; word_data[1] += idata[i*w->out_size+1]; unsigned long long *head_tail_flag = &idata[i*w->out_size+2]; if((i!=out_task_num-1)&& (head_tail_flag[1] == 1) && (head_tail_flag[4] == 0)) { flag_cal_sum++; } } word_data[0] += flag_cal_sum; for (int i = status_num-1; i >=0; i--) { s->printf("%llu ",word_data[i]); } return 0; } \end{verbatim} \fi