view paper/gearsOS.tex @ 27:5927917e1832

update
author mir3636
date Mon, 04 Feb 2019 18:02:37 +0900
parents 64a07484a5f3
children d5bca3bca59c
line wrap: on
line source

\chapter{Gears OS の構成}
Gears OS は Code Gear、 Data Gear の単位を用いて開発されており、CbC で記述されている。

Gears OS は以下の要素で構成される。


・Context

・TaskManager

・TaskQueue

・Workers

図\ref{fig:gearsos} に Gears OS の構成図を示す。

\begin{figure}[ht]
 \begin{center}
  \includegraphics[width=160mm]{./fig/gears_structure}
 \end{center}
 \caption{Gears OS の構成図}
 \label{fig:gearsos}
\end{figure}

%Context は Task でもあり、Taskは通常のOSのスレッドに対応する。
%Task は実行する Code Gear と Data Gear をすべて持っている。
TaskManager は Task を実行する Worker の生成、管理、Task の送信を行う。
Gears OS における Task Queue は Synchronized Queue で実現される。
Worker は TaskQueue から Task である Context を取得し、Task の Code Gear を実行し、Output Data Gear の書き出しを行っている。
Input/Output Data Gear の依存関係が解決されたものから並列実行される。

TaskManager は Task である Context の生成を行う。
実行する Task の Input Data Gear が揃っているなら TaskQueue へ put する。
Worker は Task の取得を行い、Task を実行する。
Task 実行後 Data Gear の書き出しを行い、再び Task の取得を行う。
Data Gear の依存関係が解決されると Task Queue に Task が送り込まれる。

\section{Context}
Context は実行する Code Gear と Data Gear を全て持っている Meta Data Gear である。
Context は通常の OS のスレッドに対応する。
また Context は並列実行における Task の表現としても用いられる。
Context は、ソースコード \ref{contexth} のように定義されている。
Context は、実行される Task への Code Gear や、
ソースコード \ref{contexth} 5、6行目で記述されているように Code Gear のリスト、Data Gear のリスト、
Data Gear を確保するためのメモリ空間を持っている。
Context が持つ Data Gear のメモリ空間は事前に確保され、
Data Gear のメモリ確保の際に heap の値をずらしメモリを割り当てる。

ソースコード \ref{contexth} 13〜30行目は並列実行用の Task として扱うための情報である。
待ち合わせの Input Data Gear のカウンタ、Input/Output Data Gear が格納されている場所を示すインデックス、
GPU での実行フラグを持っている。


Gears OS では Data Gear は構造体で定義されている。
メタ計算では任意の Data Gear を一律で扱うため、全て union で定義されている。(ソースコード \ref{contexth} 33行目〜)
Context には Data Gear の Data Type の情報が格納されている。
この情報から確保する Data Gear のサイズなどを決定する。

\lstinputlisting[label=contexth, caption=Context]{./src/context.h}

Context は、ソースコード \ref{enumCodeh} のように Code Gear の番号を持っており。
初期化の際に Code Gear のアドレスと対応付けている。(ソースコード \ref{initContext})

\begin{lstlisting}[frame=lrbt,label=enumCodeh,caption={\footnotesize enum で定義された Code Gear の番号}]
enum Code {
    C_popSingleLinkedStack,
    C_pushSingleLinkedStack,
    C_stackTest3,
    C_assert3,
    ...
};
\end{lstlisting}

\begin{lstlisting}[frame=lrbt,label=initContext,caption={\footnotesize Context の初期化}]
    context->code[C_popSingleLinkedStack] = popSingleLinkedStack_stub;
    context->code[C_pushSingleLinkedStack]  = pushSingleLinkedStack_stub;
    context->code[C_stackTest3] = stackTest3_stub;
    context->code[C_assert3] = assert3_stub;
\end{lstlisting}

Data Gear も Code Gear と同様に Context が番号を持っている。(ソースコード \ref{enumDatah})
Context の初期化の際に引数格納用の Data Gear が生成される。
この Data Gear は Code Gear が継続する際に、継続先の Code Gear が要求する引数を格納するためのものである。
生成された Data Gear は data のリストと番号の対応から参照される。

\begin{lstlisting}[frame=lrbt,label=enumDatah,caption={\footnotesize enum で定義された Data Gear の番号}]
enum DataType {
    D_Code,
    D_SingleLinkedStack,
    D_Stack,
    D_TaskManager,
    D_Worker,
    ...
};
\end{lstlisting}

\section{TaskManager}
TaskManager は、CPU、GPU の数に応じた Worker の生成、管理、Task の送信を行う。
ソースコード \ref{TaskManager} は TaskManager の Interface である。


TaskManager は、初期化の際にそれぞれ指定した CPU、GPU の数の Worker を生成する。
また、実行する Task の Input Data Gear が用意されているかどうか判断し、
全て用意されていた場合、その Task を Worker の Queue に送信する。

\lstinputlisting[label=TaskManager, caption=TaskManager の Interface]{./src/taskManagerInterface.cbc}
\section{TaskQueue}

Gears OS における TaskQueue は Synchronized Queue で実現される。
Worker TaskQueue は TaskManager を経由して Task を送信するスレッドと、
Task を取得する Worker 自身のスレッドで扱われる。
Gears OS の TaskQueue はマルチスレッドでの操作を想定しているため、データの一貫性を保証する必要がある。
そのため、データの一貫性を並列実行時でも保証するために Compare and Swap(CAS) を利用して Queue の操作を行っている。
CAS はデータの比較・置換をアトミックに行う命令である。
メモリからデータの読みだし、変更、メモリへのデータの書き出しという一連の処理を CAS を利用することで
処理の間に他のスレッドがメモリに変更を加えないことを保証することができる。
CAS に失敗した場合は置換を行わず、再びデータの呼び出しから始める。

\section{Workers}

Worker は自身の Queue から Task を取得し、Task の Code Gear を実行し、Output Data Gear の書き出しを行っている。
Worker は初期化の際に スレッドを生成する。
生成されたスレッドはまず、Context を生成する。
Context をスレッド毎に生成することで、メモリ空間をスレッド毎に持てるため他のスレッドを止めることはない。
Context の生成後は Queue から Task を取得する。
Task は Context で実現されているため Worker 自身の Context と Context である Task を入れ替え、Task を実行する。
Task の実行後に Data Gear の書き出しと依存関係の解決を行う。
その後、Context を Worker の Context に入れ替え、再び Task を取得する。