view paper/example.tex @ 5:b824fc3885be

chapter 4
author Masataka Kohagura <e085726@ie.u-ryukyu.ac.jp>
date Thu, 17 Apr 2014 18:04:14 +0900
parents c030ccbf279a
children c2aa5573dd39
line wrap: on
line source

\section{Cerium Task Manager を使った例題}

\subsection{ファイルの読み込みに関する例題}
テキストファイルをある一定のサイズに分割して読み込むプログラムである。このプログラムでは、pread という関数で実装した。
pread 関数は UNIX 標準に関するヘッダファイル、unistd.h に含まれている関数である。(表\ref{table:pread})
読み込んだテキストファイルはバッファに格納されるが、その格納先は TaskManager の API でメモリを確保している。
\begin{tiny}
  \begin{table}[ht]
    \begin{center}
      \label{table:pread}
      \small
        ssize\_t pread(int fd, void *buf, size\_t nbyte, off\_t offset);
      \begin{tabular}[t]{c|l}
        \hline
        int fd & 読み込むファイルディスクリプタ \\
        \hline
        void *buf & 予め用意したバッファへの書き込み \\
        \hline
        size\_t nbyte & 読み込むサイズ \\
        \hline
        off\_t offset& ファイルの先頭からのオフセット \\
        \hline
      \end{tabular}
      \caption{pread 関数の概要}
    \end{center}
  \end{table}
\end{tiny}

この例題の Task 生成部分を以下に示す。
\\

\begin{verbatim}
HTaskPtr read = manager->create_task(Read_task);
read->set_cpu(SPE_ANY);

read->set_param(0,(long)task_number);
read->set_param(1,(long)division_size);
if(read_left_size <= division_size){
    read->set_param(2,(long)left_size);
}else{
    read->set_param(2,(long)division_size);
}
read->set_param(3,(long)fd);

read->set_outData(0,read_text +
        task_number*division_size, division_size);
read->spawn();

left_size -= division_size;
task_number++;
\end{verbatim}

\begin{tiny}
  \begin{table}[ht]
    \begin{center}
      \label{table:pread}
      \begin{tabular}[t]{c|l}
        \hline
        int task\_number & 生成された Task ID \\
        \hline
        division\_size & 1 つの Read Task が読み込む量\\
        \hline
        left\_size & 残りの読み込み量\\
        \hline
        int fd &  ファイルディスクリプタ\\
        \hline
        read\_text & 読み込み時に格納する場所の先頭アドレス\\
        \hline
      \end{tabular}
      \caption{Read Task の生成}
    \end{center}
  \end{table}
\end{tiny}

% 
% read という Task を宣言し、read に対して CPU Type、生成した Task の番号 task\_number、
% 1つの Task が読み込み量 division\_size、ファイルディスクリプタ fd を設定する。
% 読み込んだデータの格納先を set\_outData にて設定を行い Task を生成する。
% 
% Task が生成されると、division\_size分の読み込みを行ったということで、残りの読み込み量 read\_left\_size から division\_size を引き、そして task\_numberを増加させる。
% task\_number は ファイルサイズを division\_size で割った数だけ生成され、もし余りがあれば更に1加えた数になる。
% その数が Read Task の数となり、その数だけループ処理を行う。
% 中盤にある if 文は、最後の Read Task かどうかで実際に読み込む量が決定される。
% 
read Task の記述を以下に示す。

\begin{verbatim}
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;
}
\end{verbatim}

生成時に設定したデータ群を受け取り、それらのデータを pread の引数に渡す。読み込まれたファイルは read\_text に格納される。

ハードディスクに保存されている 10GB のテキストファイルを分割して読み込み終わるまでの時間を下記に示す。
分割サイズとは、1回の読み込み量である。
\begin{tiny}
  \begin{table}[ht]
    \begin{center}
      \label{table:preaddata}
      \small
      \begin{tabular}[t]{c|l}
        \hline
        分割サイズ & 読み込み速度(s)\\
        \hline
        16KB & 391.7 \\
        \hline
        16MB & 123.6 \\
        \hline
      \end{tabular}
    \end{center}
  \end{table}
\end{tiny}

分割サイズを大きくすると、pread の呼ばれる回数が少なくなるので読み込むことが速くなる。

\subsection{Word Count}
hogehoge

\newpage