Mercurial > hg > Papers > 2014 > masakoha-sigos
diff paper/cerium.tex @ 12:6f6f482b9f12
fix
author | Masataka Kohagura <e085726@ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 20 Apr 2014 22:21:07 +0900 |
parents | 91662ffcaf0b |
children | 5bdd06f52b61 |
line wrap: on
line diff
--- a/paper/cerium.tex Sun Apr 20 16:25:41 2014 +0900 +++ b/paper/cerium.tex Sun Apr 20 22:21:07 2014 +0900 @@ -1,6 +1,5 @@ \section{Cerium TaskManager}\label{section:cerium} -\subsection{Cerium Task Manager の概要} Cerium Task Manager は並列プログラミングフレームワークであり、内部では C や C++ で実装されている。 Cerium Task Manager は、User が並列処理を Task 単位で記述し、関数やサブルーチンを Task として扱い、その Task に対して Input Data、Output Data 及び依存関係を設定する。 そして、それに基づいた設定の元で Task Manager にて管理し実行される。 @@ -17,32 +16,29 @@ \label{fig:cerium} \end{figure} -\subsection{Cerium Task Manager の利用方法} +\newpage + +\subsection{Cerium Task Manager を使った例題} +今回計測に使用した例題 WordCount を例にとり、以下に Task の生成部分を以下に示す。 +このプログラムは、WordCount Task と Print Task の2種類の Task から構成される。 -input Data で格納して 2 つの数を乗算し、output data に格納する multiply という例題がある。 -その例題の Task 生成部分を以下に示す。 +input data とは、mmap や read で読み込んだファイルであり、このファイルを $ n $ KByte の大きさに分割して、WordCount Task にそれぞれ割り当てる。 -\newpage +WordCount Task は、input された data の単語数と行数をカウントし、それらを output に指定された data 領域に書きこむ。 + +以下に WordCount の Task 生成部分を示す。 \begin{verbatim} -multi_init(TaskManager *manager) -{ - float *A, *B, *C; - HTaskPtr multiply = manager-> - create_task(MULTIPLY_TASK); - multiply->set_cpu(SPE_ANY); - multiply->set_inData - (0, (memaddr)A, - sizeof(float)*length); - multiply->set_inData - (1, (memaddr)B, - sizeof(float)*length); - multiply->set_outData - (0, (memaddr)C, - sizeof(float)*length); - multiply->set_param(0,(long)length); - multiply->spawn(); -} +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} @@ -54,11 +50,9 @@ \hline create\_task& Task を生成する \\ \hline - set\_inData & Task への入力データのアドレスを追加 \\ + set\_inData & Task に入力データのアドレスを追加 \\ \hline - set\_outData & Task への出力データのアドレスを追加 \\ - \hline - set\_param & Task へ値を一つ渡す。ここでは length \\ + set\_outData & Task に出力データのアドレスを追加 \\ \hline set\_cpu & Task を実行するデバイスの設定 \\ \hline @@ -70,21 +64,47 @@ \end{table} \end{tiny} +しかし、input data は分割されたデータが送られてくるため、分割された前後のテキストがどうなっているかはわからない。 +そのため担当範囲であるデータの先頭と末尾のパラメータを単語数と行数の他に付け加える。後にそのデータを他の WordCount の結果と照らし合わせ、分割されたテキストを正しく整合する。 Task の記述は以下のようになる。 \\ \begin{verbatim} -static int -run(SchedTask *s,void *rbuf, void *wbuf) +wordcount(SchedTask *s, void *rbuf, void *wbuf) { - float *A, *B, *C; - A = (float*)s->get_input(rbuf,0); - B = (float*)s->get_input(rbuf,1); - C = (float*)s->get_output(wbuf,0); - long length=(long)s->get_param(0); - for (int i=0;i<length;i++) { - C[i]=A[i]*B[i]; + 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} @@ -107,3 +127,56 @@ \end{center} \end{table} \end{tiny} + +Print Task は WordCount Task によって書き出された単語数と行数を集計し、結果を出力する Task である。 +WordCount Task が全て走り終わったあとに、Print Task が走るように wait をかけている。(図\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} + +単語数や行数、そして担当範囲の先頭と末尾の文字列の状態を配列としてデータを保持している。 +その配列を 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}