0
|
1 \chapter{Cerium}
|
4
|
2 Cerium は、当初 Cell 用の Fine-Grain TaskManager として当研究室で開発された。
|
|
3 本章では Cerium の実装について説明する。
|
|
4
|
|
5 \section{Cerium の概要}
|
|
6 Cerium は当初 Cell 用であったが、現在では Linux、 MaxOS X上で動作する。
|
|
7 GPGPU の Data Parallel を含めて同じ形式で記述できる。
|
|
8
|
|
9 CeriumはTaskManager、 SceneGraph、Rendering Engine の3つの要素から構成される。
|
|
10 本研究では Cerium の TaskManager を汎用計算フレームワークとして改良を行う。
|
|
11 これによりヘテロジニアス環境に対応したシステムやフレームワークに必要な API や機構について考察していく。
|
|
12 \section{Cerium TaskManager}
|
|
13 Cerium TaskManager では、処理の単位を Task としてプログラムを記述していく。
|
|
14 関数やサブルーチンを Task として扱い、 Task 間の依存関係を考慮しながら実行される。
|
|
15 Task を生成する際に、以下のような要素を設定することができる。
|
|
16
|
|
17 \begin{itemize}
|
|
18 \item input data
|
|
19 \item output data
|
|
20 \item parameter
|
|
21 \item cpu type
|
|
22 \item dependency
|
|
23 \end{itemize}
|
|
24
|
|
25 input/output data, parameter は関数で言うところの引数に相当する。
|
|
26 cpu type は Task が動作する Device を示し、 dependency は他の Task との依存関係を表す。
|
|
27
|
|
28 \section{Cerium における Task}
|
|
29 図:\ref{fig:taskmanager}は Cerium が Task を生成/実行する場合のクラスの構成図である。
|
|
30 TaskManager で依存関係が解消され、実行可能になった Task は ActiveTaskList に移される。
|
|
31 ActiveTaskList に移された Task は依存関係が存在しないのでどのような順番で実行されても良い。
|
|
32 Task は転送を行いやすい TaskList に変換され、cpu type に対応した Scheduler に転送される。
|
|
33 なお、転送はSynchronozed Queue である mail を通して行われる。
|
0
|
34
|
|
35
|
4
|
36 \begin{figure}[htpb]
|
|
37 \begin{center}
|
|
38 \includegraphics[scale=0.7]{./images/createTask.pdf}
|
|
39 \end{center}
|
|
40 \caption{Task Manager}
|
|
41 \label{fig:taskmanager}
|
|
42 \end{figure}
|
0
|
43
|
4
|
44 \section{Task の Scheduling}
|
|
45 Scheduler に転送された Task はパイプラインで処理される(図:\ref{fig:scheduler})。
|
|
46 Task が全て終了すると Scheduler から TaskManager に mail を通して通知される。
|
|
47 通知に従い依存関係を解決した Task が再び TaskManager から Scheduler に転送される。
|
|
48
|
|
49 \begin{figure}[htpb]
|
|
50 \begin{center}
|
|
51 \includegraphics[scale=0.7]{./images/scheduler.pdf}
|
|
52 \end{center}
|
|
53 \caption{Scheduler}
|
|
54 \label{fig:scheduler}
|
|
55 \end{figure}
|
|
56 \newpage
|
|
57 \section{Task 生成の例}
|
|
58 ソースコード:\ref{src:createTask}に Task を生成する例題を示す。
|
|
59 input data を2つ用意し、 input data の各要素同士を乗算し、
|
|
60 output に格納する multiply という例題である。
|
|
61
|
|
62 \begin{lstlisting}[frame=lrbt,label=src:createTask,caption=Task の生成,numbers=left]
|
|
63 void
|
|
64 multiply_init(TaskManager *manager, float *i_data1, float *i_data2, float *o_data) {
|
|
65
|
|
66 // create task
|
|
67 HTask* multiply = manager->create_task(MULTIPLY_TASK);
|
|
68 multiply->set_cpu(spe_cpu);
|
|
69
|
|
70 // set indata
|
|
71 multiply->set_inData(0, i_data1, sizeof(float) * length);
|
|
72 multiply->set_inData(1, i_data2, sizeof(float) * length);
|
|
73
|
|
74 // set outdata
|
|
75 multiply->set_outData(0, o_data, sizeof(float) * length);
|
|
76
|
|
77 // set parameter
|
|
78 multiply−>set_param(0,(long)length);
|
|
79
|
|
80 // set device
|
|
81 multiply->set_cpu(SPE_ANY);
|
|
82
|
|
83 // spawn task
|
|
84 multiply−>spawn();
|
|
85 }
|
|
86 \end{lstlisting}
|
|
87
|
|
88 表:\ref{table:task_create_api}は Task 生成時に用いる API の一覧である。
|
|
89 create された Task は各種パラメタを設定し、spawn/iterate することで TaskManager に登録される。
|
0
|
90
|
4
|
91 \begin{tiny}
|
|
92 \begin{table}[htpb]
|
|
93 \begin{center}
|
|
94 \small
|
|
95 \begin{tabular}[htpb]{c|l}
|
|
96 \hline
|
|
97 create\_task & Task を生成する \\
|
|
98 \hline
|
|
99 set\_inData & Task への入力データのアドレスを追加 \\
|
|
100 \hline
|
|
101 set\_outData & Task からの出力データのアドレスを追加 \\
|
|
102 \hline
|
|
103 set\_param & Task へ値を一つ渡す。ここではlengthを渡している \\
|
|
104 \hline
|
|
105 set\_cpu & Task を実行する Device の設定 \\
|
|
106 \hline
|
|
107 spawn & 生成した Task を ActiveTaskList に登録する \\
|
|
108 \hline
|
|
109 \end{tabular}
|
|
110 \caption{Task 生成おける API}
|
|
111 \label{table:task_create_api}
|
|
112 \end{center}
|
|
113 \end{table}
|
|
114 \end{tiny}
|
0
|
115
|
4
|
116 ソースコード:\ref{src:createTask}は Host 側で Task を生成しているプログラムである。
|
|
117 Device 側で実行される Task (OpenCL、CUDA でいう kernel) の記述はソースコード:\ref{src:task}のようになる。
|
0
|
118
|
4
|
119 \begin{lstlisting}[frame=lrbt,label=src:task,caption=Task,numbers=left]
|
|
120 static int
|
|
121 run(SchedTask *s) {
|
|
122 // get input
|
|
123 float *i_data1 = (float*)s->get_input(0);
|
|
124 float *i_data2 = (float*)s->get_input(1);
|
|
125 // get output
|
|
126 float *o_data = (float*)s->get_output(0);
|
|
127 // get parameter
|
|
128 long length = (long)s->get_param(0);
|
|
129
|
|
130 // calculate
|
|
131 for (int i=0; i<length; i++) {
|
|
132 o_data[i] = i_data1[i] * i_data2[i];
|
|
133 }
|
|
134 return 0;
|
|
135 }
|
|
136 \end{lstlisting}
|
|
137
|
|
138 表:\ref{table:task_api}は Task 側で使用する API である。
|
|
139
|
|
140 \begin{tiny}
|
|
141 \begin{table}[htpb]
|
|
142 \begin{center}
|
|
143 \small
|
|
144 \begin{tabular}[htpb]{c|l}
|
|
145 \hline
|
|
146 get\_input & 入力データのアドレスを取得 \\
|
|
147 \hline
|
|
148 set\_inData & 出力先データのアドレスを取得 \\
|
|
149 \hline
|
|
150 set\_outData & パラメータを取得 \\
|
|
151 \hline
|
|
152 \end{tabular}
|
|
153 \caption{Task 側で使用する API}
|
|
154 \label{table:task_api}
|
|
155 \end{center}
|
|
156 \end{table}
|
|
157 \end{tiny}
|