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}