# HG changeset patch # User Masataka Kohagura # Date 1397725454 -32400 # Node ID b824fc3885be0b3079a601392388553a56413cff # Parent c030ccbf279a83041219e0a87867ddb2f7ec8a98 chapter 4 diff -r c030ccbf279a -r b824fc3885be paper/example.tex --- a/paper/example.tex Thu Apr 17 15:31:56 2014 +0900 +++ b/paper/example.tex Thu Apr 17 18:04:14 2014 +0900 @@ -3,7 +3,7 @@ \subsection{ファイルの読み込みに関する例題} テキストファイルをある一定のサイズに分割して読み込むプログラムである。このプログラムでは、pread という関数で実装した。 pread 関数は UNIX 標準に関するヘッダファイル、unistd.h に含まれている関数である。(表\ref{table:pread}) -読み込んだテキストファイルはバッファに格納されるが、その格納先は TaskManager の API でメモリを確保する。 +読み込んだテキストファイルはバッファに格納されるが、その格納先は TaskManager の API でメモリを確保している。 \begin{tiny} \begin{table}[ht] \begin{center} @@ -46,21 +46,44 @@ task_number*division_size, division_size); read->spawn(); -read_left_size -= division_size; +left_size -= division_size; task_number++; \end{verbatim} -read という Task を宣言し、Task に対して CPU Type、パラメータとして生成した Task 番号の task\_number -1つの Task の読み込み量 division\_size、読み込むファイルのファイルディスクリプタ fd を設定する。 -読み込んだデータの格納先を set\_outData にて設定を行い、そして spawn にて Task を生成する。 +\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} -Task が生成されると、division\_size分の読み込みを行ったということで、残りの読み込み量 read\_left\_size から division\_size を引き、そして task\_numberを増加させる。 -この Task 生成部分は ファイルサイズ を division\_size で割った数だけ生成され、もし余りがあれば更に1加えた数になる。 -その数が Read Task の数となり、その数だけループ処理を行う。 -中盤にある if 文は、最後の Read Task かどうかで実際に読み込む量が決定される。 +% +% 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 の記述を以下に示す。 -read Task の記述を以下に示す。 -\\ \begin{verbatim} static int read_task(SchedTask *s, void *rbuf, void *wbuf) @@ -70,10 +93,10 @@ long read_size = (long)s->get_param(2); long fd = (long)s->get_param(3); - char *read_text = + char *read_text = (char*)s->get_output(wbuf,0); - pread(fd, read_text, (long)read_size , + pread(fd, read_text, (long)read_size, division_size*task_number); return 0; } @@ -105,3 +128,5 @@ \subsection{Word Count} hogehoge + +\newpage diff -r c030ccbf279a -r b824fc3885be paper/io.tex --- a/paper/io.tex Thu Apr 17 15:31:56 2014 +0900 +++ b/paper/io.tex Thu Apr 17 18:04:14 2014 +0900 @@ -2,15 +2,10 @@ \subsection{mmap での実装と問題点} mmap とは、sys/mman.h に含まれている関数で、ファイルの読み込み等に使用される関数である。 -ファイルディスクリプタで指定したファイルを offset から len バイトの範囲を読み込む。 -この時にアドレス addr からメモリを確保するようにする。 -prot には、PROT\_READによるページの読み込み、PROT\_WRITEによるページへの書き込みなどを指定でき、 -flags にはメモリ確保する際のオプションを指定することができる。(表\ref{table:mmap}) \begin{tiny} \begin{table}[ht] \begin{center} - \label{table:mmap} \small void * mmap(void *addr, size\_t len, int prot, int flags, int fd, off\_t offset); @@ -31,14 +26,21 @@ \hline \end{tabular} \caption{mmap 関数の概要} + \label{table:mmap} \end{center} \end{table} \end{tiny} +ファイルディスクリプタで指定したファイルを offset から len バイトの範囲を読み込む。 +この時にアドレス addr からメモリを確保するようにする。 +prot には、PROT\_READによるページの読み込み、PROT\_WRITEによるページへの書き込みなどを指定でき、 +flags にはメモリ確保する際のオプションを指定することができる。(表\ref{table:mmap}) + + mmap でファイルを読み込むタイミングは、mmap 関数が呼ばれたときではなく、mmap した領域に対して何らかのアクセスをしたときに初めてファイルが読み込まれる。 図\ref{fig:mmap}では、読み込んだファイルを分割して、それらの領域に何らかの処理を加えるときの図である。これらの処理を Task と呼ぶ。 -Task 1 という1個目の Task が実行される。実行されたときに初めてそれらの領域にファイルが読み込まれ、その後何らかの処理が行われ、そして Task 2 も同様に読み込みを行ってから処理が行われる。 +1個目の Task が実行されるときに初めてそれらの領域にファイルが読み込まれ、その後何らかの処理が行われ、そして Task 2 も同様に読み込みを行ってから処理が行われる。 これら Task は並列に実行されるべきであるが、ファイル読み込みの I/O 部分がネックとなり、本来並列実行される Task が読み込み待ちを起こしてしまう恐れがある。 その上、読み込み方法が OS 依存となるために環境によって左右されやすく、プログラムの書き手が読み込みに関して制御しにくい。 @@ -64,7 +66,6 @@ \begin{tiny} \begin{table}[ht] \begin{center} - \label{table:pread} \small ssize\_t pread(int d, void *buf, size\_t nbyte, off\_t offset); @@ -80,6 +81,7 @@ \hline \end{tabular} \caption{pread 関数の概要} + \label{table:pread} \end{center} \end{table} \end{tiny} @@ -108,9 +110,10 @@ もし、Task Block が Blocked Read よりも先走ってしまうとどうなるであろうか。 まだ読み込まれていない領域に対して何らかの処理を行ってしまうので、正しい結果が返ってこなくなってしまう。 -それを防止するために、Blocked Read が読み込み終わってから Task Block が起動されるように wait をかけている。 +それを防止するために、Blocked Read が読み込み終わってから Task Block が起動されるように Cerium の API である wait\_for にて依存関係を設定する。 (図\ref{fig:block}) + \begin{figure}[htbp] \begin{center} \includegraphics[scale=0.35]{images/blockreadtask.pdf} @@ -119,7 +122,6 @@ \label{fig:block} \end{figure} - \subsection{I/O 専用 thread の実装} Cerium Task Manager では、各種 Task にデバイスを設定することができる。 @@ -135,7 +137,7 @@ \label{fig:speany} \end{figure} -この問題を解決するために、Task Manager に新しく I/O 専用の thread 、 IO\_0 の追加を行った。 +この問題を解決するため、Cerium Task Manager に新しく I/O 専用の thread 、 IO\_0 の追加を行った。 %(図\ref{fig:addio0}) %%この問題を解決するために、Task Manager に IO\_0という新しいデバイス設定を追加した。