annotate slide/index.md @ 24:876d6c1bc7e6

revision
author Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
date Fri, 19 Feb 2016 05:26:22 +0900
parents f147f579d552
children 7fc1656c2819
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
17
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 title: Code Segment と Data Segment を持つ Gears OS の設計
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
2 author: Shohei KOKUBO
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
3 profile: 琉球大学大学院修士2年
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
4
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
5 # 並列環境下におけるプログラミング
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
6 マルチコア CPU の性能を発揮するには、処理をできるだけ並列化しなければならない。
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 これはアムダールの法則により、並列化できない部分が並列化による性能向上を制限することから言える。
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 つまり、プログラムを並列処理に適した形で記述するためのフレームワークが必要になる。
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
9
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
10 マルチコア CPU 以外にも GPU や CPU と GPU を複合したヘテロジニアスなプロセッサが登場している。
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
11 並列処理をする上でこれらのリソースを無視することはできない。
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 しかし、これらのプロセッサで性能を引き出すためにはそれぞれのアーキテクチャに合わせた並列プログラミングが必要になる。
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 並列プログラミングフレームワークではこれらのプロセッサを抽象化し、CPU と同等に扱えるようにすることも求められる。
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
14
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
15 # Cerium
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
16 Cerium は本研究室で開発している並列プログラミングフレームワークである。
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
17
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 Cerium では関数またはサブルーチンを Task として定義する。
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
19 Task 間で依存関係を設定することができ、TaskManager が依存関係を解決することで実行可能な状態となる。
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
20 実行可能な状態となると Task に設定された実行デバイスの Scheduler に転送され実行される。
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
21
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
22 ![Cerium の構成](./pictures/createTask.svg)
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
23
24
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
24 # Cerium における GPGPU への対応
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
25 * OpenCL, CUDA を用いて GPGPU に対応している
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
26 * GPGPU ではメモリ空間が異なるためデータ転送が大きなオーバーヘッドになる
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
27 * 処理速度を上げるにはデータ転送をオーバーラップする必要がある
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
28
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
29 ![GPU](./pictures/gpu.svg)
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
30
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
31 # Cerium における GPGPU への対応
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
32 * Stream に命令を発行することで GPU を制御する
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
33 * Stream は命令が発行された順番通りに実行されることを保証する
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
34 * 複数の Stream を用意し、各 Stream に命令を発行することでデータ転送をオーバーラップすることができる
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
35
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
36 ![stream](./pictures/stream.svg)
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
37
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
38 # Bitonic Sort を用いた Cerium の評価
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
39 * Bitonic Sort は並列処理に向いたソートアルゴリズムである
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
40 * 最初から最後まで並列度が変わらず、台数による効果が出やすい
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
41
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
42 ![bitonic](./pictures/bitonic.svg)
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
43
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
44 # Bitonic Sort を用いた Cerium の評価
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
45 * 測定環境
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
46 * Model : MacPro Mid 2010
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
47 * OS : Mac OS X 10.10.5
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
48 * Memory : 16GB
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
49 * CPU : 2 x 6-Core Intel Xeon 2.66GHz
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
50 * GPU : NVIDIA Quadro K5000
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
51 * Cores : 1536
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
52 * Clock Speed : 706MHz
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
53 * Memory : 4GB GDDR5
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
54 * Memory Bandwidth : 173 GB/s
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
55 * 要素数:2<sup>20</sup>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
56
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
57 <table border="1" align='center' width='50%'>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
58 <tbody>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
59 <tr>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
60 <td style="text-align: center;">Processor</td>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
61 <td style="text-align: center;">Time(ms)</td>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
62 </tr>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
63 <tr>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
64 <td style="text-align: center;">1 CPU</td>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
65 <td style="text-align: right;">6143</td>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
66 </tr>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
67 <tr>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
68 <td style="text-align: center;">2 CPUs</td>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
69 <td style="text-align: right;">4633</td>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
70 </tr>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
71 <tr>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
72 <td style="text-align: center;">4 CPUs</td>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
73 <td style="text-align: right;">2577</td>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
74 </tr>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
75 <tr>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
76 <td style="text-align: center;">8 CPUs</td>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
77 <td style="text-align: right;">1630</td>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
78 </tr>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
79 <tr>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
80 <td style="text-align: center;">12 CPUs</td>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
81 <td style="text-align: right;">1318</td>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
82 </tr>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
83 <tr>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
84 <td style="text-align: center;">GPU</td>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
85 <td style="text-align: right;">155</td>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
86 </tr>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
87 </tbody>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
88 </table>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
89
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
90 <table width="70%" align="center">
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
91 <tr>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
92 <td><div align="center"><img src="pictures/bitonic_box.svg" width="1024"></div></td>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
93 </tr>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
94 </table>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
95
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
96 # Bitonic Sort を用いた Cerium の評価
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
97 次に要素数を変更して測定を行った。
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
98
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
99 <table width="70%" align="center">
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
100 <tr>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
101 <td><div align="center"><img src="pictures/bitonic_all.svg" width="1024"></div></td>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
102 </tr>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
103 <tr>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
104 <td><div align="center"><img src="pictures/bitonic_part.svg" width="1024"></div></td>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
105 </tr>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
106 </table>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
107
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
108 GPU による実行ではデータ転送の時間を考慮する必要がある。
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
109
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
110 GPGPU は大きなデータに対して有効であることがわかる。
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
111
19
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
112 # Cerium の問題点
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
113 * Task 間の依存関係
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
114
17
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
115 Cerium では Task 間の依存関係を設定することで並列処理を実現する。
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
116 しかし、本来 Task は必要なデータが揃うことで実行可能になるものである。
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
117 Task 同士の依存関係だけでは前の Task が不正な処理を行いデータがおかしくなっても Task の終了は通知され、そのまま処理が続行されてしまう。
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
118 データがどこでおかしくなったのか特定するのは難しく、デバックに時間が取られる。
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
119
19
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
120 * データの型情報
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
121
17
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
122 Task は汎用ポインタでデータの受け渡しを行うのでそこで型情報が落ちる。
19
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
123 Task 側で正しく型変換を行うことで正しい処理を行うことができるが、誤った型変換を行うと未定義な動作となりデータ構造を破壊する可能性がある。
17
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
124 型システムによるプログラムの正しさを保証することもできず、型に基づく一連の不具合が起こる危険性がつきまとう。
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
125
19
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
126 # Cerium の問題点
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
127 * メモリ確保
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
128
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
129 Cerium の Allocator は Thread 間で共有されている。
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
130 ある Thread がメモリを確保しようとすると他の Thread はその間メモリを確保することができない。
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
131 これが並列度の低下に繋がり、処理速度が落ちる原因になる。
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
132
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
133 * オブジェクト指向と並列処理
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
134
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
135 同じ入力に対し、同じ入力を返すことが保証される参照透過な処理は並列化を行いやすい。
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
136 一方、オブジェクト指向は保守性と再利用性を高めるためにカプセル化やポリモフィズムを重視する。
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
137 オブジェクトの状態によって振る舞いが変わるため並列処理との相性が悪い。
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
138
17
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
139 # Gears OS
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
140 本研究では Code Segment と Data Segment によって構成される Gears OS の設計・実装を行った。
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
141
19
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
142 Code/Data Segment で分割して記述することでプログラム全体の並列度を高めて効率的に並列処理することを可能にする。
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
143
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
144 Gears OS の基本的な機能の実装には本研究室で開発している CbC(Continuation based C) を用いた。
17
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
145
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
146 # Code/Data Gear
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
147 Gears OS ではプログラムの単位として Gear を用いる。
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
148 Gear は並列実行の単位、データ分割、Gear 間の接続などになる。
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
149
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
150 Code Gear は Code Segment と同等のものである。
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
151 Code Gear には任意の数の Data Gear を参照し、処理が完了すると任意の数の Data Gear に書き込みを行う。
20
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
152 接続された Data Gear 以外にアクセスすることはできない。
17
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
153
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
154 Data Gear はデータそのものを表す。
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
155 int や文字列などの Primitive Data Type を複数持つ構造体として定義する。
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
156
19
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
157 Gear 特徴として処理やデータの構造が Code/Data Gear に閉じていることにある。
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
158 これにより実行時間、メモリ使用量などを予測可能なものにする。
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
159
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
160 # Gears OS の構成
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
161 * Context
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
162
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
163 接続可能な Code/Data Gear のリスト、TaskQueue へのポインタ、Persistent Data Tree へのポインタ、独立したメモリ空間を持っている。
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
164 複数の Context で TaskQueue と Persistent Data Tree は共有される。
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
165
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
166 * TaskQueue
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
167
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
168 ActiveTaskQueue と WaitTaskQueue の2種類の TaskQueue がある。
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
169 ActiveTaskQueue には実行可能な Task が挿入され、WaitTaskQueue には依存関係が解決されていない Task が挿入される。
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
170 先頭と末尾の Element へのポインタを持つ Data Gear と Task へのポインタと次の Element へのポインタを持つ Data Gear で構成される。
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
171 Compare and Swap(CAS) を利用することでスレッドセーフに Queue を操作することができる。
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
172
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
173 # Gears OS の構成
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
174 * Persistent Data Tree
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
175
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
176 Data Gear の管理を行う。
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
177 非破壊木構造で構成されるため読み書きを平行して行うことができる。
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
178 Red-Black Tree アルゴリズムを用いて平衡性を保ち、挿入・削除・検索における計算量を保証する。
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
179 Persistent Data Tree への書き込みのみで相互作用を発生させ目的の処理を達成する。
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
180
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
181 * TaskManager
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
182
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
183 Gears OS における Task は実行する Code Gear と Input/Output Data Gear の組で表現される。
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
184 Input/Output Data Gear から依存関係を決定する。
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
185 TaskManager は Persistent Data Tree を監視し、Task の依存関係を解決する。
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
186
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
187 # Gears OS の構成
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
188 * Worker
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
189
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
190 Worker は ActiveTaskQueue から Task を取得する。
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
191 取得した Task の情報を元に必要な Data Gear を Persistent Data Tree から取得し、Code Gear を実行する。
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
192 実行後、必要なデータを Persistent Data Tree に書き出し次の Task を取得する。
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
193
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
194 ![Gears OS の構成](./pictures/gearsos.svg)
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
195
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
196 # Allocator
20
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
197 * Context の生成時にある程度の大きさのメモリ領域を確保
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
198 * Context には確保したメモリ領域を指す情報(heapStart, heap, heapLimit)を格納
19
4dcfec1bf1e7 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 17
diff changeset
199
20
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
200 ``` C
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
201 /* Context definition example */
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
202 #define ALLOCATE_SIZE 1000
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
203
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
204 // Code Gear Name
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
205 enum Code {
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
206 Code1,
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
207 Code2,
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
208 Allocator,
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
209 Exit,
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
210 };
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
211
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
212 // Unique Data Gear
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
213 enum UniqueData {
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
214 Allocate,
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
215 };
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
216
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
217 struct Context {
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
218 enum Code next;
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
219 int codeNum;
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
220 __code (**code) (struct Context*);
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
221 void* heapStart;
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
222 void* heap;
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
223 long heapLimit;
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
224 int dataNum;
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
225 union Data **data;
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
226 };
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
227
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
228 // Data Gear definition
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
229 union Data {
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
230 // size: 4 byte
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
231 struct Data1 {
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
232 int i;
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
233 } data1;
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
234 // size: 5 byte
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
235 struct Data2 {
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
236 int i;
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
237 char c;
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
238 } data2;
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
239 // size: 8 byte
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
240 struct Allocate {
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
241 long size;
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
242 } allocate;
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
243 };
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
244 ```
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
245
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
246 # Allocator
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
247 * Allocation を行うための情報を書き込む Data Gear が必要
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
248 * Context と同時に生成
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
249 ``` C
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
250 __code initContext(struct Context* context, int num) {
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
251 context->heapLimit = sizeof(union Data)*ALLOCATE_SIZE;
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
252 context->heapStart = malloc(context->heapLimit);
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
253 context->heap = context->heapStart;
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
254 context->codeNum = Exit;
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
255
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
256 context->code = malloc(sizeof(__code*)*ALLOCATE_SIZE);
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
257 context->data = malloc(sizeof(union Data*)*ALLOCATE_SIZE);
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
258
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
259 context->code[Code1] = code1_stub;
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
260 context->code[Code2] = code2_stub;
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
261 context->code[Allocator] = allocator_stub;
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
262 context->code[Exit] = exit_code;
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
263
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
264 context->data[Allocate] = context->heap;
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
265 context->heap += sizeof(struct Allocate);
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
266
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
267 context->dataNum = Allocate;
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
268 }
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
269 ```
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
270
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
271 # Allocator
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
272 * メモリ領域を指すポインタを動かすことで Data Gear のメモリを確保
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
273 * 確保した Data Gear は基本的に破棄可能なものである
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
274 * リニアにメモリを確保し、サイズを超えたら先頭に戻って再利用
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
275
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
276 ![Allocator](./pictures/allocation.svg)
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
277
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
278 # Allocator
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
279 * Allocation に必要な情報を Data Gear に書き込み、Allocator に接続する
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
280 * 生成した Data Gear には Context を介してアクセスすることができるが、Context を直接扱うのは好ましくない
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
281 * Context から値を取り出すだけのメタレベルの Code Gear を用意
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
282
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
283 ``` C
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
284 // Meta Code Gear
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
285 __code meta(struct Context* context, enum Code next) {
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
286 // meta computation
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
287 goto (context->code[next])(context);
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
288 }
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
289
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
290 // Code Gear
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
291 __code code1(struct Context* context, struct Allocate* allocate) {
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
292 allocate->size = sizeof(struct Data1);
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
293 context->next = Code2;
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
294
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
295 goto meta(context, Allocator);
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
296 }
17
5b584f09d356 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents:
diff changeset
297
20
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
298 // Meta Code Gear(stub)
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
299 __code code1_stub(struct Context* context) {
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
300 goto code1(context, &context->data[Allocate]->allocate);
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
301 }
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
302
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
303 // Meta Code Gear
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
304 __code allocator(struct Context* context, struct Allocate* allocate) {
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
305 context->data[++context->dataNum] = context->heap;
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
306 context->heap += allocate->size;
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
307
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
308 goto meta(context, context->next);
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
309 }
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
310
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
311 // Meta Code Gear(stub)
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
312 __code allocator_stub(struct Context* context) {
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
313 goto allocator(context, &context->data[Allocate]->allcate);
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
314 }
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
315
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
316 // Code Gear
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
317 __code code2(struct Context* context, struct Data1* data1) {
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
318 // processing
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
319 }
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
320
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
321 // Meta Code Gear(stub)
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
322 __code code2_stub(struct Context* context) {
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
323 goto code2(context, &context->data[context->dataNum]->data1);
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
324 }
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
325 ```
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
326
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
327 # TaskQueue
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
328 TaskQueue は Task を管理する。
24
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
329
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
330 すべての Context で共有され、CAS 命令を利用して変更することで平行にアクセスされてもデータの一貫性を保証する。
20
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
331
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
332 * 先頭と末尾の要素へのポインタを持った Queue を表す Data Gear
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
333 * Task と次の要素へのポインタを持った Element を表す Data Gear
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
334 ``` C
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
335 // Code Gear Name
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
336 enum Code {
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
337 PutQueue,
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
338 GetQueue,
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
339 };
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
340
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
341 // Unique Data Gear
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
342 enum UniqueData {
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
343 Queue,
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
344 Element,
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
345 };
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
346
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
347 // Queue definication
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
348 union Data {
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
349 // size: 20 byte
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
350 struct Queue {
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
351 struct Element* first;
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
352 struct Element* last;
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
353 int count;
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
354 } queue;
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
355 // size: 16 byte
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
356 struct Element {
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
357 struct Task* task;
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
358 struct Element* next;
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
359 } element;
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
360 }
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
361 ```
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
362
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
363 # TaskQueue の操作(Enqueue)
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
364 * Enqueue は Queue の最後の要素を取り出し、次の要素に追加する要素を設定
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
365 * Queue を表す Data Gear が指す末尾を追加する要素に設定
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
366 * 正しく最後の要素が取り出せたことを保証して末尾の変更を行う必要がある
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
367
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
368 ``` C
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
369 // Enqueue
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
370 __code putQueue(struct Context* context, struct Queue* queue, struct Element* new_element) {
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
371 struct Element* last = queue->last;
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
372
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
373 if (__sync_bool_compare_and_swap(&queue->last, last, new_element)) {
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
374 last->next = new_element;
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
375 queue->count++;
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
376
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
377 goto meta(context, context->next);
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
378 } else {
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
379 goto meta(context, PutQueue);
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
380 }
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
381 }
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
382 ```
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
383
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
384 # Persistent Data Tree
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
385 * Data Gear の管理を行う
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
386 * 複数の Context で共有
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
387 * 一度構築した木構造を破壊することなく新しい木構造を構築するので平行して読み書き可能
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
388 * 非破壊木構造の基本的な戦略はルートから変更したいノードへのパスをすべてコピーし、パス上に存在しないノードはコピー元の木構造と共有する
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
389
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
390 ![非破壊木構造](./pictures/tree.svg)
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
391
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
392 # Persistent Data Tree
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
393 * 木構造を構築するとき最悪なケースでは事実上の線形リストになり、計算量が O(n) となる
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
394 * 挿入・削除・検索における処理時間を保証するために Red-Black Tree アルゴリズムを用いて木構造の平衡性を保つ
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
395 * Red-Black Tree では変更したノードからルートに上りながら条件を満たすように色の変更や木の回転を行う
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
396 * Code Gear の継続では呼び出し元に戻ることが出来ないので Context に辿ったパスを記憶するためのスタックを準備する。
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
397
e077497754a0 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 19
diff changeset
398 ```C
23
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
399 // Unique Data Gear
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
400 enum UniqueData {
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
401 Tree,
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
402 Traverse,
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
403 Node,
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
404 };
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
405
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
406 // Context definication
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
407 struct Context {
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
408 stack_ptr node_stack;
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
409 };
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
410
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
411 // Red-Black Tree definication
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
412 union Data {
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
413 // size: 8 byte
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
414 struct Tree {
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
415 struct Node* root;
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
416 } tree;
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
417 // size: 12 byte
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
418 struct Traverse {
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
419 struct Node* current;
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
420 int result;
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
421 } traverse;
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
422 // size: 32 byte
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
423 struct Node {
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
424 int key;
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
425 union Data* value;
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
426 struct Node* left;
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
427 struct Node* right;
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
428 enum Color {
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
429 Red,
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
430 Black,
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
431 } color;
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
432 } node;
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
433 };
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
434 ```
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
435
f147f579d552 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 20
diff changeset
436 # Persistent Data Tree
24
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
437 * 親を取得し、親からの参照を変更して親をスタックに積み直す
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
438 * 自分と左右の3点のノードで回転を行うことで平衡にする
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
439 * 回転後も条件を満たしているか確認する必要がある
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
440
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
441 ```C
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
442 // Code Gear
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
443 __code rotateLeft(struct Context* context, struct Node* node, struct Tree* tree, struct Traverse* traverse) {
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
444 struct Node* tmp = node->right;
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
445 struct Node* parent = 0;
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
446
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
447 stack_pop(context->node_stack, &parent);
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
448
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
449 if (parent) {
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
450 if (node == parent->left)
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
451 parent->left = tmp;
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
452 else
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
453 parent->right = tmp;
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
454 } else {
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
455 tree->root = tmp;
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
456 }
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
457
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
458 stack_push(context->node_stack, &parent);
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
459
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
460 node->right = tmp->left;
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
461 tmp->left = node;
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
462 traverse->current = tmp;
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
463
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
464 stack_pop(context->code_stack, &context->next);
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
465 goto meta(context, context->next);
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
466 }
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
467
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
468 // Meta Code Gear(stub)
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
469 __code rotateLeft_stub(struct Context* context) {
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
470 goto rotateLeft(context,
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
471 context->data[Traverse]->traverse.current,
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
472 &context->data[Tree]->tree,
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
473 &context->data[Traverse]->traverse);
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
474 }
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
475 ```
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
476
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
477 # Worker
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
478 * TaskQueue から Task を取得して実行
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
479 * TaskQueue へのアクセスには CAS 命令を用いる
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
480 * Task には実行する Code Gear と実行に必要な Data Gear の key が格納されている
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
481 * Task が完了したら次の Task を取得するために GetQueue に戻ってくる必要がある
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
482 * CAS に失敗したら CAS をやり直すために自分自身に継続する
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
483
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
484 ```C
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
485 // Task definication
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
486 union Data {
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
487 // size: 8 byte
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
488 struct Task {
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
489 enum Code code;
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
490 int key;
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
491 } task;
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
492 }
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
493 ```
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
494
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
495 ```C
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
496 // Dequeue
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
497 __code getQueue(struct Context* context, struct Queue* queue, struct Node* node) {
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
498 if (queue->first == 0)
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
499 return;
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
500
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
501 struct Element* first = queue->first;
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
502 if (__sync_bool_compare_and_swap(&queue->first, first, first->next)) {
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
503 queue->count--;
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
504
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
505 context->next = GetQueue;
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
506 stack_push(context->code_stack, &context->next);
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
507
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
508 context->next = first->task->code;
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
509 node->key = first->task->key;
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
510
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
511 goto meta(context, GetTree);
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
512 } else {
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
513 goto meta(context, GetQueue);
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
514 }
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
515 }
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
516 ```
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
517
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
518 # Worker
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
519 * Worker で実行される Code Gear は特別なものではなく、他の Code Gear と同じ記述である
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
520 * 依存関係のない Code Gear はすべて並列に動作させることができることを意味する
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
521 * Gears OS 自体が Code Gear によって構成され、Gears OS の実装自体が Gears Programming の指針となる
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
522
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
523 ```C
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
524 // Code Gear
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
525 __code twice(struct Context* context, struct LoopCounter* loopCounter, int index, int alignment, int* array) {
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
526 int i = loopCounter->i;
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
527
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
528 if (i < alignment) {
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
529 array[i+index*alignment] = array[i+index*alignment]*2;
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
530 loopCounter->i++;
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
531
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
532 goto meta(context, Twice);
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
533 }
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
534
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
535 loopCounter->i = 0;
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
536
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
537 stack_pop(context->code_stack, &context->next);
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
538 goto meta(context, context->next);
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
539 }
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
540
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
541 // Meta Code Gear(stub)
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
542 __code twice_stub(struct Context* context) {
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
543 goto twice(context,
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
544 &context->data[LoopCounter]->loopCounter,
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
545 context->data[Node]->node.value->array.index,
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
546 context->data[Node]->node.value->array.alignment,
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
547 context->data[Node]->node.value->array.array);
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
548 }
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
549 ```
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
550
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
551 # TaskManager
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
552 * TaskManager は Task の依存関係の解決を行う
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
553 * Worker の起動・停止も行う
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
554
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
555 ```C
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
556 // Code Gear
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
557 __code createWorker(struct Context* context, struct LoopCounter* loopCounter, struct Worker* worker) {
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
558 int i = loopCounter->i;
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
559
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
560 if (i < worker->num) {
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
561 struct Context* worker_context = &worker->contexts[i];
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
562 worker_context->next = GetQueue;
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
563 worker_context->data[Tree] = context->data[Tree];
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
564 worker_context->data[ActiveQueue] = context->data[ActiveQueue];
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
565 pthread_create(&worker_context->thread, NULL, (void*)&start_code, worker_context);
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
566 worker_context->thread_num = i;
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
567 loopCounter->i++;
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
568
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
569 goto meta(context, CreateWorker);
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
570 }
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
571
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
572 loopCounter->i = 0;
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
573 goto meta(context, TaskManager);
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
574 }
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
575
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
576 // Meta Code Gear
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
577 __code createWorker_stub(struct Context* context) {
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
578 goto createWorker(context,
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
579 &context->data[LoopCounter]->loopCounter,
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
580 &context->data[Worker]->worker);
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
581 }
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
582 ```
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
583
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
584 # Gears OS の評価
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
585 * Red-Black Tree アルゴリズムに基づいて非破壊木構造で構築される Persistent Data Tree
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
586 * CAS 命令を用いてアクセスすることで並列に動作させてもデータの一貫性を保証する TaskQueue
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
587 * TaskQueue から Task を取得し実行する Worker
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
588
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
589 Gears OS を用いて依存関係のない並列処理を実行可能な状態となった
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
590
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
591 簡単な並列処理の例題を実装し、評価を行う
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
592
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
593 # Twice
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
594 依存関係のない簡単な例題として Twice を実装した
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
595
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
596 Twice は与えられた整数配列を2倍にする例題である
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
597
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
598 * 配列のサイズを元に処理範囲と処理量を決める index, alignment, 配列へのポインタを持つ Data Gear に分割
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
599 * Data Gear を Persistent Data Tree に挿入
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
600 * 実行する Code Gear(Twice) と実行に必要な Data Gear の key を持つ Task を生成
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
601 * 生成した Task を TaskQueue に挿入
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
602 * Worker の起動
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
603 * Worker が TaskQueue から Task を取得
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
604 * 取得した Task を元に必要な Data Gear を Persistent Data Tree から取得
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
605 * Code Gear(Twice) を実行
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
606
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
607 # Result
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
608 * 要素数:2<sup>17</sup> * 1000 elements
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
609 * 分割数:640 tasks
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
610 * 1 Task 当たりの処理量:2<sup>11</sup> * 100 elements
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
611
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
612 <table border="1" align='center' width='50%'>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
613 <tbody>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
614 <tr>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
615 <td style="text-align: center;">Number of Processors</td>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
616 <td style="text-align: center;">Time(ms)</td>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
617 </tr>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
618 <tr>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
619 <td style="text-align: center;">1 CPU</td>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
620 <td style="text-align: right;">1315</td>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
621 </tr>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
622 <tr>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
623 <td style="text-align: center;">2 CPUs</td>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
624 <td style="text-align: right;">689</td>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
625 </tr>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
626 <tr>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
627 <td style="text-align: center;">4 CPUs</td>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
628 <td style="text-align: right;">366</td>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
629 </tr>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
630 <tr>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
631 <td style="text-align: center;">8 CPUs</td>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
632 <td style="text-align: right;">189</td>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
633 </tr>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
634 <tr>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
635 <td style="text-align: center;">12 CPUs</td>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
636 <td style="text-align: right;">111</td>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
637 </tr>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
638 </tbody>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
639 </table>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
640
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
641 <table width="70%" align="center">
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
642 <tr>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
643 <td><div align="center"><img src="pictures/twice.svg" width="1024"></div></td>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
644 </tr>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
645 </table>
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
646
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
647 1 CPU と 12 CPU で約11.8倍の速度向上を確認した
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
648
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
649 十分な台数効果が出ていることがわかる
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
650
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
651 # まとめ
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
652 * Cerium を開発して得られた知見から Code/Data Segment を持つ Gears OS を設計した
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
653 * 基本的な機能として Allocator, TaskQueue, Persistent Data Tree, Worker を実装した
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
654 * 実装した基本的な機能を組み合わせ Gears OS のプロトタイプを作成し、依存関係のない簡単な並列処理の例題を実装した
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
655 * Gears OS がオーバーヘッドにならず、十分な台数効果が出ることを確認した
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
656 * Gears OS の実装自体が Gears OS を用いて並列処理を記述する際の指針となるように実装した
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
657
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
658 # 今後の課題
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
659 * 一般的に並列処理には依存関係が存在する。
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
660 複雑な並列処理を実行できるようにするために依存関係を解決する TaskManager を実装する必要がある
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
661 * GPU など他のプロセッサを演算に利用することができない。
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
662 Code/Data Segment を用いて各プロセッサにのアーキテクチャにマッピングした実行機構を実装する必要がある
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
663 * Data Segment 専用の構文を用意するべきである。
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
664 いまの実装では必要ない Data Segment を持つ場合がある。
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
665 実行可能な Code Segment のリストから推論し必要な Data Segment のみを持つようにする必要がある
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
666 * Data Segment の型情報を検査する機能がない。
876d6c1bc7e6 revision
Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
parents: 23
diff changeset
667 型シグネチャを導入し、プログラムの正しさを保証する型システムを Gears OS 上に実装する必要がある