view paper/chapter4.tex @ 50:22740fb4d522

write mmap
author masa
date Fri, 21 Feb 2014 00:26:56 +0900
parents e8dd2f96d046
children 06f75bca7a70
line wrap: on
line source

\chapter{並列処理向け I/O の設計と実装}
\label{chap:poordirection}

\section{map reduce}

\begin{figure}[htbp]
\begin{center}
\includegraphics[width=1.0\textwidth]{fig/mapreduce.pdf}
\end{center}
\caption{map reduce image}
\label{fig:mmap} \end{figure} 

\section{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);

      \begin{tabular}[t]{c|l}
        \hline
        void *addr &  メモリに確保するときの先頭のアドレス\\
        \hline
        size\_t len &  メモリを確保するサイズ\\
        \hline
        int prot &  ファイルモード選択\\
        \hline
        int flags &  確保するときのオプション指定\\
        \hline
        int fd &  読み込むファイルのファイルディスクリプタ\\
        \hline
        off\_t offset & ファイル読み込みの先頭からの開始位置 \\
        \hline
      \end{tabular}
      \caption{mmap 関数の概要}
    \end{center}
  \end{table}
\end{tiny}

mmap でファイルを読み込むタイミングは、mmap 関数が呼ばれたときではなく、mmap した領域に対して何らかのアクセスをしたときに初めてファイルが読み込まれる。

図\ref{fig:mmap}では、読み込んだファイルを分割して、それらの領域に何らかの処理を加えるときの図である。これらの処理を Task と呼ぶ。
Task 1 という1個目の Task が実行される。実行されたときに初めてそれらの領域にファイルが読み込まれ、その後何らかの処理が行われ、そして Task 2 も同様に読み込みを行ってから処理が行われる。
これら Task は並列に実行されるべきであるが、ファイル読み込みの I/O 部分がネックとなり、本来並列実行される Task が読み込み待ちを起こしてしまう恐れがある。
その上、読み込み方法が OS 依存となるために環境によって左右されやすく、プログラムの書き手が読み込みに関して制御しにくい。

それらを解決するためには、ファイル読み込みと Task を分離し、ファイルの読み込みも制御しやすくでき、なおかつ高速で動くのではないかと考えた。

\begin{figure}[htbp]
\begin{center}
\includegraphics[width=1.0\textwidth]{fig/mmap.pdf}
\end{center}
\caption{mmap のイメージ}
\label{fig:mmap} \end{figure} 

\section{Broked Read の設計と実装}
・ I/O を mmap ではなく、pread 関数で実装した

・ pread の概要

・ pread で実装すると、自分自身で制御できる。

・ TaskManager で allocate して、Task として呼び出した pread で allocate 部分に格納している

・ pread で実装したものを、Task と IO が並列に動くようにしないといけない

・ pread は常に走っていているのが理想


図\ref{fig:mmap}

\begin{figure}[htbp]
\begin{center}
\includegraphics[width=1.0\textwidth]{fig/blockedreadimage.pdf}
\end{center}
\caption{[image]blocked read image}
\label{fig:mmap}
\end{figure}

・ これで IO と Task が同時にはしるようになった

・ 実験結果??

・ Task は実際には 1個1個生成しているのではなく

・ Cerium の Task に CPU Type を設定することができる。しかし、同じCPU Type を使用すると、IO を担当している CPU に Task が割り振られて、read 全体の速度が遅くなってしまう。


図\ref{fig:speany}

\begin{figure}[htbp]
\begin{center}
\includegraphics[width=1.0\textwidth]{fig/speany.pdf}
\end{center}
\caption{[image]priority を上げる前の image 図}
\label{fig:speany}
\end{figure}


\section{I/O 専用 thread の実装}
・ Cerium では ptherad で並列処理を記述している

・ SPY\_ANY という CPU Type は、Cerium 側が自動的に CPU 割り当てを行う便利なマクロ

・ SPE\_ANY を使用すると、IO の部分にも割り込まれてしまうので、これをどうにかしたい。

・ IO\_0 という新しい CPU Type を追加

・ pthread の API で CPU の priority をあげることができる。


図\ref{fig:io0}

\begin{figure}[htbp]
\begin{center}
\includegraphics[width=1.0\textwidth]{fig/io0.pdf}
\end{center}
\caption{[image]priority を上げたときの image 図}
\label{fig:io0}
\end{figure}

・ これで IO 部分に割り込みがおこらないよね!!