Mercurial > hg > Papers > 2017 > ikkun-sigos
comparison presen/sigos.md~ @ 30:3050872e76df
merge
author | ikkun |
---|---|
date | Tue, 16 May 2017 01:19:23 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
29:ebf75ff50c46 | 30:3050872e76df |
---|---|
1 title: Gears OSにおける並列処理 | |
2 author: 東恩納 琢偉 | |
3 profile: 琉球大学理工学研究科 | |
4 lang: Japanese | |
5 code-engine: coderay | |
6 ## Gears OS | |
7 - 当研究室では 処理の単位を Code Gear、 データの単位を Data Gear を用いて | |
8 - 並列性 | |
9 - 柔軟性 | |
10 - 信頼性 | |
11 | |
12 を指標とした Gears OS を設計してきた | |
13 | |
14 - 本研究では Gears OS のプロトタイプとして並列処理機構を Continuation based C(CbC) で実装を行う | |
15 | |
16 ## Gears OS の並列性 | |
17 - Gears OS はプログラムの単位として Gear を用いる | |
18 - Gear には プログラムの処理を示す Code Gear、 Data を示す Data Gear がある | |
19 - Code/Data Gear を用いて記述することでプログラム全体の並列度を高め、効率的に並列処理することが可能 | |
20 | |
21 <div style="text-align: center;"> | |
22 <img src="./images/codeGear_dataGear.svg" alt="message" width="450"> | |
23 </div> | |
24 | |
25 ## Gears OS の柔軟性 | |
26 - Gears OS は Meta Computation を使用することで | |
27 - データ拡張や機能の追加 | |
28 - GPU 等のさまざまなアーキテクチャでも同じプログラムの動作 | |
29 - バージョンが異なる者同士がネットワーク接続しても通信 | |
30 | |
31 等を柔軟に対応する | |
32 | |
33 - Meta Computation は 通常の Computaiton と階層を分けて処理を行う | |
34 | |
35 <div style="text-align: center;"> | |
36 <img src="./images/meta_gear.svg" alt="message" width="800"> | |
37 </div> | |
38 | |
39 ## Gears OS の信頼性 | |
40 - 検証 | |
41 - モデル検査を行う | |
42 - モデル検査は状態の数が膨大になると検査するのが難しい | |
43 - そのため、不必要な状態である環境やスタックをなるべく取り除き、処理を行う | |
44 - 証明 | |
45 - Code Gear と Data Gear を理論的に定義 | |
46 | |
47 ## この発表は | |
48 - Gears OS でのGear | |
49 - Meta Computation | |
50 - Continuation based C(CbC) | |
51 - CbC を用いた Gears OS の記述 | |
52 - Gears OS の並列処理のプロトタイプ | |
53 - まとめ | |
54 - 課題 | |
55 | |
56 ## Code Gear、 Data Gear | |
57 - Gears OS は Code Gear、 Data Gear という Gear で構成される | |
58 - Code Gear はプログラムの処理そのものを表す | |
59 - Data Gear は int や 文字列などの Data そのものを表す | |
60 - Code Gear は必要な Input Data Gear が揃ったら実行し、 Output Data Gear を生成する | |
61 - Code Gear と Input / Output Data Gear の対応から依存関係を解決し、 Code Gear の並列実行を行う | |
62 | |
63 <div style="text-align: center;"> | |
64 <img src="./images/codeGear_dataGear_dependency.svg" alt="message" width="600"> | |
65 </div> | |
66 | |
67 | |
68 ## Meta Computation | |
69 - Meta Computation は通常の Computation のための Computation | |
70 - 並列処理の依存関係の解決、 GPUなどのアーキテクチャでの実行のために行う処理などを行う | |
71 - Gears OS では Meta Computation を Meta Code Gear, Meta Data Gear で表現 | |
72 | |
73 ## Meta Gear | |
74 - Meta Computation は Code/Data Gearの接続の間に行われる | |
75 - Meta Computation の処理も Code/Data Gear で実現する | |
76 - この Gear を Meta Code/Data Gearと呼ぶ | |
77 - Meta Code Gear は Meta Computation のプログラム部分 | |
78 - Meta Data Gear は Meta Code Gear で管理されるデータ部分 | |
79 - Gears OS は通常の Code/Data Gear から Meta Code/Data Gear 接続部分は見えないように実装を行う | |
80 | |
81 <div style="text-align: center;"> | |
82 <img src="./images/meta_cg_dg.svg" alt="message" width="850"> | |
83 </div> | |
84 | |
85 | |
86 ## Continuation based C | |
87 - Gears OS の実装は本研究室で開発している Continuation based C(CbC) を用いる | |
88 - CbC は処理を Code Segment を用いて記述する事を基本とする | |
89 - Code Segment は Code Gear を同等のものため、 Gears OS を記述するのに適している | |
90 | |
91 ## Continuation based C | |
92 - Code Segment の定義は ``__code CS名`` で行う | |
93 - Code Segment 間は ``goto CS名`` で移動する。この移動を継続と呼ぶ | |
94 - Code Segment の継続は C の関数呼び出しとは異なり、戻り値を持たないためスタックの変更を行わない | |
95 - このような環境を持たない継続を軽量継続と呼ぶ | |
96 | |
97 ## Continuation based C | |
98 - このコードは code1、code2 の2つの Code Segment を定義している | |
99 - code1 内の ``goto code2`` でcode2 への継続を行っている | |
100 | |
101 ``` c | |
102 /* code1 define */ | |
103 __code code1(List list) { | |
104 .... | |
105 goto code2(list) | |
106 } | |
107 | |
108 /* code2 define */ | |
109 __code code2(List list) { | |
110 ... | |
111 } | |
112 ``` | |
113 | |
114 ## CbC を用いた Gears OS の記述 | |
115 - Gears OS での Code Gear も Code Segment の定義のように記述する | |
116 - 各 Code Gear の引数は 必要な Data Gear を示す | |
117 - このコードでは 2つの Code Gear と 1つの Meta Code Gear を定義しており、 code1 から code2への継続を行っている | |
118 | |
119 ``` c | |
120 __code code1(struct Array* array, struct LoopCounter* loopCounter) { | |
121 ... | |
122 goto code2(array); | |
123 } | |
124 | |
125 __code meta_code1(struct Context* context, enum Code next) { | |
126 goto (context->code[next])(context); | |
127 } | |
128 | |
129 __code code2(struct Array* array) { | |
130 ... | |
131 } | |
132 ``` | |
133 | |
134 ## CbC の Gears OS サポート | |
135 - 実際は code1 から code2 への継続の間には Meta Code Gear である meta_code1 が実行される | |
136 - 通常は Meta Level の継続をプログラマーは意識する必要はない | |
137 - そこで、CbC は Code Gear 間の接続に自動的に Meta Code Gear を挟むというサポートを行う | |
138 - CbC のサポートを行うとこのコードのように展開される | |
139 - メタレベルのサポートの際は **context** という Meta Data Gear を使用する | |
140 | |
141 ``` c | |
142 __code code1(struct Context* context, struct Array* array, struct LoopCounter* loopCounter) { | |
143 ... | |
144 goto meta_code1(context, Code2); | |
145 } | |
146 | |
147 __code code1_stub(struct Context* context) { | |
148 goto code1(context, &context->data[Node]->node.value->array, &context->data[LoopCounter]->loopCounter); | |
149 } | |
150 | |
151 __code meta_code1(struct Context* context, enum Code next) { | |
152 goto (context->code[next])(context); | |
153 } | |
154 | |
155 __code code2(struct Context* context, struct Array* array) { | |
156 ... | |
157 } | |
158 ``` | |
159 | |
160 ## Context | |
161 - Context は | |
162 - 接続可能な Code/Data Gear のリスト | |
163 - 独立したメモリ空間 | |
164 をもっている | |
165 | |
166 - 各 Code/Data Gear にアクセスする際は Context を経由する | |
167 | |
168 ## Context | |
169 - Context は | |
170 - 実行可能な Code Gear の数を示す **codeNum** | |
171 - 実行可能な Code Gear のリストを示す **code** | |
172 - Data Gear の Allocate 用の **heapStart**, **heap**, **heapLimit** | |
173 - Data Gear の数を示す **dataNum** | |
174 - Data Gear のリストを示す **data** | |
175 で構成される | |
176 | |
177 ``` c | |
178 /* context define */ | |
179 struct Context { | |
180 int codeNum; | |
181 __code (**code) (struct Context*); | |
182 void* heapStart; | |
183 void* heap; | |
184 long heapLimit; | |
185 int dataNum; | |
186 union Data **data; | |
187 }; | |
188 ``` | |
189 | |
190 ## Context | |
191 - 実行可能な Code Gear の名前は **enum code** で定義する | |
192 - Context の初期化時に名前と関数ポインタを対応付ける | |
193 - 現在の Gears ではこの enum code 使って接続先の Code Gear を指定する | |
194 | |
195 ``` c | |
196 enum Code { | |
197 Code1, | |
198 Code2, | |
199 Code3, | |
200 Exit, | |
201 }; | |
202 ``` | |
203 | |
204 ## Data Gear の表現 | |
205 - 使用する Data Gear は C の共用体と構造体を用いた表現をする | |
206 - これを元に Gears OS は 必要な Data Gear を allocate する | |
207 | |
208 ``` c | |
209 /* data Gear define */ | |
210 union Data { | |
211 struct Time { | |
212 enum Code next; | |
213 double time; | |
214 } time; | |
215 struct LoopCounter { | |
216 int i; | |
217 } loopCounter; | |
218 .... | |
219 }; | |
220 ``` | |
221 | |
222 ## Code Gear の stub | |
223 - Data Gear にアクセスするにはContext を経由する | |
224 - だが、通常の Code Gear では Meta Data Gear である Context の参照は避ける必要がある | |
225 - Gears OS では通常の Code Gear で必要な Data Gear を Context から取り出す stub を用意する | |
226 - stub は一種の Meta Code Gear であるため、 CbC で自動生成される | |
227 - このコードでは Array と LoopCounter が必要な code1 の stub を示している | |
228 | |
229 ``` c | |
230 __code code1(struct Context* context, struct Array* array, struct LoopCounter* loopCounter) { | |
231 ... | |
232 } | |
233 | |
234 /* stub define */ | |
235 __code code1_stub(struct Context* context) { | |
236 goto code1(context, &context->data[Node]->node.value->array, &context->data[LoopCounter]->loopCounter); | |
237 } | |
238 ``` | |
239 | |
240 ## プロトタイプ の構成 | |
241 - 今回は並列処理を行う機構の実装を行う | |
242 - 必要な要素は大きく5つ | |
243 - Context | |
244 - TaskQueue | |
245 - 実行される Task のリストを扱う | |
246 - Persistent Data Tree | |
247 - Code Gear によって参照される Data Gear の管理を行う | |
248 - Worker | |
249 - TaskQueue から Task を取得し、実行する | |
250 - TaskManager | |
251 - Persistent Data Tree を監視し、 Task の依存関係を解決する | |
252 | |
253 ※ TaskManager は今回未実装 | |
254 | |
255 ## TaskQueue | |
256 - Task Queue は Task のリストを扱う | |
257 - すべての Thread で共有されるため、 Compare And Swap(CAS) を使用した Synchronized Queue として実装する | |
258 - TaskQueue は 2つで Data Gear で表現される | |
259 - 先頭と末尾の要素を持った Queue 表す Data Gear | |
260 - Task と次の要素へのポインタを持った、リスト構造を表現する Element という Data Gear | |
261 | |
262 ``` c | |
263 // Data Gear define | |
264 union Data { | |
265 struct Queue { | |
266 struct Element* first; | |
267 struct Element* last; | |
268 } queue; | |
269 | |
270 struct Element { | |
271 struct Task* task; | |
272 struct Elemen* next; | |
273 } element | |
274 }; | |
275 ``` | |
276 | |
277 ## TaskQueueの操作(Enqueue) | |
278 - Task を挿入する場合 Queue の last から最後の要素を取り出し、次の要素に新しく挿入する要素を設定 | |
279 - 正しく最後の要素が変更できたことを CAS で 保証し、末尾の変更を行う必要がある | |
280 | |
281 ``` c | |
282 __code putQueue3(struct Queue* queue, struct Element* new_element) { | |
283 struct Element* last = queue->last; | |
284 | |
285 if (__sync_bool_compare_and_swap(&queue->last, last, new_element)) { | |
286 last->next = new_element; | |
287 | |
288 goto exit(); | |
289 } else { | |
290 goto putQueue3(queue, new_element); | |
291 } | |
292 } | |
293 | |
294 ``` | |
295 | |
296 ## Persistent Data Tree | |
297 - Persistent Data Tree は Data Gear の管理を行う | |
298 - TaskQueue と同じですべての Thread で共有される | |
299 - Red-Black Tree アルゴリズムを用いて木構造の平衡性を保つ | |
300 - 木構造から読み出される Data Gear は Code Gear の Input Data Gear, 書き出すData Gear は Output Data Gear になる | |
301 | |
302 <div style="text-align: center;"> | |
303 <img src="./images/persistent_date_tree_2.svg" alt="message" width="800"> | |
304 </div> | |
305 | |
306 ## Persistent Data Tree | |
307 - Persistent Data Tree は | |
308 - Tree 自体を示す Data Gear | |
309 - Node を示す Data Gear | |
310 | |
311 を用いて木構造を表現する | |
312 | |
313 ``` c | |
314 union Data { | |
315 struct Tree { | |
316 struct Node* root; | |
317 } tree; | |
318 struct Node { | |
319 int key; // comparable data segment | |
320 union Data* value; | |
321 struct Node* left; | |
322 struct Node* right; | |
323 // need to balancing | |
324 enum Color { | |
325 Red, | |
326 Black, | |
327 } color; | |
328 } node; | |
329 }; | |
330 ``` | |
331 | |
332 | |
333 ## Worker | |
334 - Worker は TaskQueue から Task を取得して実行する | |
335 | |
336 <table align='center'> | |
337 <tbody> | |
338 <tr> | |
339 <td> | |
340 <div> | |
341 <img src="./images/worker.svg" alt="message" width="600"> | |
342 </div> | |
343 </td> | |
344 <td> | |
345 <ol> | |
346 <li> Worker は Task Queue から Task を取り出す(1. Dequeue Task)</li> | |
347 <li> 取り出した Task には Tree の key が入っているため Tree からその key に対応した Input Data Gear を読み込む(2. Read Data Gear) </li> | |
348 <li> Task に格納されている Code Gear を実行する </li> | |
349 <li> Code Gear を実行した結果、生成された Output Data Gear を Tree に書き出す(3.Write Data Gear) </li> | |
350 </ol> | |
351 </td> | |
352 </tr> | |
353 </tbody> | |
354 </table> | |
355 | |
356 - Task が完了したら次の Task を取得する | |
357 | |
358 ## TaskManger | |
359 - TaskManager は Task の依存関係の解決を行う | |
360 - Thread の作成と停止も行う | |
361 | |
362 <div style="text-align: center;"> | |
363 <img src="./images/taskManager.svg" alt="message" width="800"> | |
364 </div> | |
365 | |
366 | |
367 ## プロトタイプの実行 | |
368 - 今回 Gears OS の構成要素である Persistent Data Tree, TaskQueue, Worker の実装を行った | |
369 - これにより、 Gears OS を用いて依存関係のない並列処理の実行が可能になった | |
370 | |
371 ## Gears OS で実行する Code Gear 例 | |
372 - プロトタイプのタスクの例題として Twice を実装した | |
373 - Twice は与えられた整数配列を2倍にする例題である | |
374 | |
375 ``` c | |
376 // Twice Code Gear | |
377 __code twice(struct LoopCounter* loopCounter, int index, int alignment, int* array) { | |
378 int i = loopCounter->i; | |
379 | |
380 if (i < alignment) { | |
381 array[i+index*alignment] = array[i+index*alignment]*2; | |
382 loopCounter->i++; | |
383 | |
384 goto twice(loopCounter, index, alignment, array); | |
385 } | |
386 | |
387 loopCounter->i = 0; | |
388 | |
389 goto exit(); | |
390 } | |
391 ``` | |
392 | |
393 ## 並列処理の確認 | |
394 - Twice を使用し、Gears OS が実際に並列処理されているかどうかの確認を行った | |
395 - 環境 | |
396 - Memory : 16GB | |
397 - CPU : 6-core Intel Xeon 2.66GHZ x 2 | |
398 - 要素数 : 2^17 * 1000 | |
399 - 分割数 : 640 タスク | |
400 - 1 Task 当たりの処理量 : 2^11 * 100 elements | |
401 | |
402 <table border="1" align='center' width='50%'> | |
403 <tbody> | |
404 <tr> | |
405 <td style="text-align: center;">Number of Processors</td> | |
406 <td style="text-align: center;">Time(ms)</td> | |
407 </tr> | |
408 <tr> | |
409 <td style="text-align: center;">1 CPU</td> | |
410 <td style="text-align: right;">1315</td> | |
411 </tr> | |
412 <tr> | |
413 <td style="text-align: center;">2 CPUs</td> | |
414 <td style="text-align: right;">689</td> | |
415 </tr> | |
416 <tr> | |
417 <td style="text-align: center;">4 CPUs</td> | |
418 <td style="text-align: right;">366</td> | |
419 </tr> | |
420 <tr> | |
421 <td style="text-align: center;">8 CPUs</td> | |
422 <td style="text-align: right;">189</td> | |
423 </tr> | |
424 <tr> | |
425 <td style="text-align: center;">12 CPUs</td> | |
426 <td style="text-align: right;">111</td> | |
427 </tr> | |
428 </tbody> | |
429 </table> | |
430 | |
431 - 1cpu と 12cpu では 11.8 倍の向上が見られた | |
432 | |
433 | |
434 ## Cerium との比較 | |
435 - Cerium は本研究室で開発していた並列プログラミングフレームワーク | |
436 - Cerium では Task を依存関係に沿って実行することで並列実行を可能にする | |
437 - 本来 Task はデータに依存するもので Task 間の依存関係ではデータの依存関係を保証することが出来ない | |
438 - Gears OS の Task 中身は Code Gear になっており、必要な Input Data Gear が揃わない限り実行しないため、データの依存関係を保証できる | |
439 - Task には汎用ポインタとしてデータの受け渡しを行う | |
440 - 型情報がなく、型の検査を行うことが出来ない | |
441 - Gears OS では 型情報をもつ Data Gear を定義 | |
442 | |
443 ## 既存の OS への対応 | |
444 - Gears OS は従来の OS が行ってきたネットワーク管理、メモリ管理、並行制御などのメタな部分を Meta Code/Data Gear として定義 | |
445 - 通常の Code Gear から必要な制御を Meta Code Gear で行うことで従来のOSが行ってきた制御の提供を行う | |
446 | |
447 ## まとめ | |
448 - Code Gear、 Data Gear によって構成される Gears OS の基本的な機能として TaskQueue、 Persistent Data Tree、 Worker の実装を行った | |
449 - 依存関係のない Twice を実装し、並列処理が行えることを確認した | |
450 | |
451 ## 今後の課題 | |
452 - 一般的に並列処理には依存関係が存在する | |
453 - 複雑な並列処理を実行できるようにするために Task Manager の実装を行い、 依存関係のある並列処理の例題を作成し、評価する | |
454 - GPUなどの他のプロセッサ演算に利用することが出来ない | |
455 - Data Gear などのデータをGPUにマッピングするための機構が必要 | |
456 - Gears OS でのデバック手法 | |
457 - 継続はスタックを積まないため、スタックトレースを使わないデバック手法の考案 | |
458 - 並列処理でのデバック手法も考案する必要がある | |
459 - 型情報の検査 | |
460 - プログラムの正しさを保証するために Data Gear の情報を検査するシステムを Meta Computation として実装する | |
461 - Contextの動的生成 | |
462 - 今は静的に自分で生成している | |
463 - CbC 用の Runtime をつくり、 Context を動的に生成 |