annotate paper/meta_computation.tex @ 6:7d9441dd343e

update
author mir3636
date Mon, 21 Jan 2019 18:34:24 +0900
parents 94ac73bc7829
children ddf62b739703
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
9100f20b8797 copy mitsuki-sigos
mir3636
parents:
diff changeset
1 \chapter{Gears におけるメタ計算}
9100f20b8797 copy mitsuki-sigos
mir3636
parents:
diff changeset
2 Gears OS ではメタ計算を柔軟に記述するためのプログラミング言語の単位として Code Gear、Data Gear という単位を用いる。
3
mir3636
parents: 1
diff changeset
3 プログラムの処理の単位を Code Gear、データの単位を Data Gear と呼ぶ。
5
mir3636
parents: 4
diff changeset
4
3
mir3636
parents: 1
diff changeset
5 Code Gear、Data Gear にはそれぞれメタレベルの単位である Meta Code Gear、Meta Data Gear が存在し、
mir3636
parents: 1
diff changeset
6 これらを用いてメタ計算を実現する。
5
mir3636
parents: 4
diff changeset
7
3
mir3636
parents: 1
diff changeset
8 Gears OS は処理やデータの構造が Code Gear、Data Gear に閉じているため、
mir3636
parents: 1
diff changeset
9 これにより実行時間、メモリ使用量などを予測可能なものにすることが可能になる。
mir3636
parents: 1
diff changeset
10
mir3636
parents: 1
diff changeset
11 \section{Continuation based C}
mir3636
parents: 1
diff changeset
12 CbC は処理を Code Gear とした単位を用いて記述するプログラミング言語である。
mir3636
parents: 1
diff changeset
13 Code Gear 間では軽量継続 (goto文) による遷移を行うので、継続前の Code Gear に戻ることはなく、状態遷移ベースのプログラミングに適している。
mir3636
parents: 1
diff changeset
14 図\ref{fig:cs}は Code Gear 間の処理の流れを表している。
mir3636
parents: 1
diff changeset
15
mir3636
parents: 1
diff changeset
16 \begin{figure}[htpb]
mir3636
parents: 1
diff changeset
17 \begin{center}
mir3636
parents: 1
diff changeset
18 \scalebox{0.7}{\includegraphics{fig/codesegment.pdf}}
mir3636
parents: 1
diff changeset
19 \end{center}
mir3636
parents: 1
diff changeset
20 \caption{goto による code gear 間の継続}
mir3636
parents: 1
diff changeset
21 \label{fig:cs}
mir3636
parents: 1
diff changeset
22 \end{figure}
mir3636
parents: 1
diff changeset
23
mir3636
parents: 1
diff changeset
24
mir3636
parents: 1
diff changeset
25 CbC は LLVM\cite{llvm} と GCC\cite{gcc} 上で実装されている。
mir3636
parents: 1
diff changeset
26 Gears OS はこの CbC を用いて記述されている。
mir3636
parents: 1
diff changeset
27
mir3636
parents: 1
diff changeset
28 \section{Code Gear}
mir3636
parents: 1
diff changeset
29
mir3636
parents: 1
diff changeset
30 Code Gear は CbC における最も基本的な処理単位である。
mir3636
parents: 1
diff changeset
31 リスト \ref{code_simple} はCbC における Code Gear の一例である。
mir3636
parents: 1
diff changeset
32
mir3636
parents: 1
diff changeset
33 \begin{lstlisting}[frame=lrbt,label=code_simple,caption={\footnotesize code segment の軽量継続}]
mir3636
parents: 1
diff changeset
34 __code cs0(int a, int b){
mir3636
parents: 1
diff changeset
35 goto cs1(a+b);
mir3636
parents: 1
diff changeset
36 }
mir3636
parents: 1
diff changeset
37
mir3636
parents: 1
diff changeset
38 __code cs1(int c){
mir3636
parents: 1
diff changeset
39 goto cs2(c);
mir3636
parents: 1
diff changeset
40 }
mir3636
parents: 1
diff changeset
41 \end{lstlisting}
mir3636
parents: 1
diff changeset
42
mir3636
parents: 1
diff changeset
43 Code Gear は\_\_code Code Gear 名 (引数) の形で記述される。
mir3636
parents: 1
diff changeset
44 Code Gear は戻り値を持たないので、関数とは異なり return 文は存在しない。
mir3636
parents: 1
diff changeset
45 次の Code Gear への遷移は goto Code Gear 名 (引数) で次の Code Gear への遷移を記述する。
mir3636
parents: 1
diff changeset
46 リスト \ref{code_simple} での goto cs1(a+b); がこれにあたる。
mir3636
parents: 1
diff changeset
47 この goto の行き先を継続と呼び、このときの a+b が次の Code Gear への出力となる。
mir3636
parents: 1
diff changeset
48 Scheme の継続と異なり CbC には呼び出し元の環境がないので、この継続は単なる行き先である。
mir3636
parents: 1
diff changeset
49 したがってこれを軽量継続と呼ぶこともある。
mir3636
parents: 1
diff changeset
50 cs1 へ継続した後は cs0 へ戻ることはない。
mir3636
parents: 1
diff changeset
51 軽量継続により、並列化、ループ制御、関数コールとスタックの操作を意識した最適化がソースコードレベルで行えるようにする。
mir3636
parents: 1
diff changeset
52
mir3636
parents: 1
diff changeset
53 \section{Data Gear}
mir3636
parents: 1
diff changeset
54 Data Gear は Gears におけるデータの単位である。
mir3636
parents: 1
diff changeset
55 Gears OS では Code Gear は Input Data Gear、Output Data Gear を引数に持ち、
mir3636
parents: 1
diff changeset
56 任意の Input Data Gear を参照し、Output Data Gear を書き出す。\ref{fig:IODataGear}
mir3636
parents: 1
diff changeset
57 Code Gear はこのとき渡された引数の Data Gear 以外を参照することはない。
mir3636
parents: 1
diff changeset
58 この Data Gear の対応から依存関係の解決を行う。
1
9100f20b8797 copy mitsuki-sigos
mir3636
parents:
diff changeset
59
9100f20b8797 copy mitsuki-sigos
mir3636
parents:
diff changeset
60 \begin{figure}[ht]
9100f20b8797 copy mitsuki-sigos
mir3636
parents:
diff changeset
61 \begin{center}
6
mir3636
parents: 5
diff changeset
62 \includegraphics[width=100mm]{fig/IO_DataGear.pdf}
3
mir3636
parents: 1
diff changeset
63 \end{center}
mir3636
parents: 1
diff changeset
64 \caption{CodeGear と DataGear}
mir3636
parents: 1
diff changeset
65 \label{fig:IODataGear}
mir3636
parents: 1
diff changeset
66 \end{figure}
mir3636
parents: 1
diff changeset
67
4
mir3636
parents: 3
diff changeset
68 リスト \ref{Gears_code} は Gears OS での Stack の操作の Code Gear の例である。
mir3636
parents: 3
diff changeset
69 popSingleLinkedStack での引数 stack が Input Data Gear、next は継続先の Code Gear のアドレス、
mir3636
parents: 3
diff changeset
70 next の引数の data が Output Data Gear、... は可変長引数であることを示している。
mir3636
parents: 3
diff changeset
71 pop の操作を行った後に goto next で引数で受けた次の Code Gear へと継続する。
mir3636
parents: 3
diff changeset
72
mir3636
parents: 3
diff changeset
73 \begin{lstlisting}[frame=lrbt,label=Gears_code,caption={\footnotesize Gears でのStack pop}]
mir3636
parents: 3
diff changeset
74
mir3636
parents: 3
diff changeset
75 __code stackTest3(struct Stack* stack) {
mir3636
parents: 3
diff changeset
76 goto stack->pop(assert3);
mir3636
parents: 3
diff changeset
77 }
mir3636
parents: 3
diff changeset
78
mir3636
parents: 3
diff changeset
79 __code popSingleLinkedStack(struct SingleLinkedStack* stack, __code next(union Data* data, ...)) {
mir3636
parents: 3
diff changeset
80 if (stack->top) {
mir3636
parents: 3
diff changeset
81 data = stack->top->data;
mir3636
parents: 3
diff changeset
82 stack->top = stack->top->next;
mir3636
parents: 3
diff changeset
83 } else {
mir3636
parents: 3
diff changeset
84 data = NULL;
mir3636
parents: 3
diff changeset
85 }
mir3636
parents: 3
diff changeset
86 goto next(data, ...);
mir3636
parents: 3
diff changeset
87 }
mir3636
parents: 3
diff changeset
88
mir3636
parents: 3
diff changeset
89 __code assert3(struct Node* node, struct Stack* stack) {
mir3636
parents: 3
diff changeset
90 assert(node->color == Red);
mir3636
parents: 3
diff changeset
91 goto exit_code(0);
mir3636
parents: 3
diff changeset
92 }
mir3636
parents: 3
diff changeset
93
mir3636
parents: 3
diff changeset
94 \end{lstlisting}
mir3636
parents: 3
diff changeset
95
3
mir3636
parents: 1
diff changeset
96 \section{Meta Code Gear、Meta Data Gear}
mir3636
parents: 1
diff changeset
97 Gears OS ではメタ計算 を Meta Code Gear、Meta Data Gear で表現する。
mir3636
parents: 1
diff changeset
98 Meta Code Gear は通常の Code Gear の直後に遷移され、メタ計算を実行する。
1
9100f20b8797 copy mitsuki-sigos
mir3636
parents:
diff changeset
99
3
mir3636
parents: 1
diff changeset
100 Gears OS では Context と呼ばれる、使用されるすべての Code Gear、Data Gear を持つ Meta Data Gear を持っている。
mir3636
parents: 1
diff changeset
101 Gears OS は必要な Code Gear、Data Gear を参照したい場合、この Context を通す必要がある。
mir3636
parents: 1
diff changeset
102 しかし Context を通常の計算から直接扱うのはセキュリティ上好ましくない。
mir3636
parents: 1
diff changeset
103 そこで Context から必要なデータを取り出して Code Gear に接続する Meta Code Gear を定義し、
mir3636
parents: 1
diff changeset
104 これを介して間接的に必要な Data Gear にアクセスする。
mir3636
parents: 1
diff changeset
105 この Meta Code Gear を stub Code Gear と呼ぶ。
4
mir3636
parents: 3
diff changeset
106 %code を入れる
3
mir3636
parents: 1
diff changeset
107 stub Code Gear は Code Gear 毎に生成され、次の Code Gear へと継続する前に挿入される。
mir3636
parents: 1
diff changeset
108 goto による継続を行うと、実際には次の Code Gear の stub Code Gear を呼び出す。
mir3636
parents: 1
diff changeset
109
4
mir3636
parents: 3
diff changeset
110 \section{Meta Gear の自動生成}
3
mir3636
parents: 1
diff changeset
111
4
mir3636
parents: 3
diff changeset
112 メタレベルの記述は Perl スクリプトによって生成される。
mir3636
parents: 3
diff changeset
113 stub Code Gear と meta によって Code Gear で記述される。
5
mir3636
parents: 4
diff changeset
114 リスト \ref{MetaCodeGear} は生成された Meta Code Gear のコードである。
mir3636
parents: 4
diff changeset
115
mir3636
parents: 4
diff changeset
116 \begin{lstlisting}[frame=lrbt,label=Gears_code,caption={\footnotesize MetaCodeGear}]
mir3636
parents: 4
diff changeset
117
mir3636
parents: 4
diff changeset
118 __code popSingleLinkedStack_stub(struct Context* context) {
mir3636
parents: 4
diff changeset
119 SingleLinkedStack* stack = (SingleLinkedStack*)GearImpl(context, Stack, stack);
mir3636
parents: 4
diff changeset
120 enum Code next = Gearef(context, Stack)->next;
mir3636
parents: 4
diff changeset
121 Data** O_data = &Gearef(context, Stack)->data;
mir3636
parents: 4
diff changeset
122 goto popSingleLinkedStack(context, stack, next, O_data);
mir3636
parents: 4
diff changeset
123 }
mir3636
parents: 4
diff changeset
124
mir3636
parents: 4
diff changeset
125 __code popSingleLinkedStack(struct Context *context,struct SingleLinkedStack* stack, enum Code next,union Data **O_data) {
mir3636
parents: 4
diff changeset
126 Data* data = *O_data;
mir3636
parents: 4
diff changeset
127 if (stack->top) {
mir3636
parents: 4
diff changeset
128 data = stack->top->data;
mir3636
parents: 4
diff changeset
129 stack->top = stack->top->next;
mir3636
parents: 4
diff changeset
130 } else {
mir3636
parents: 4
diff changeset
131 data = NULL;
mir3636
parents: 4
diff changeset
132 }
mir3636
parents: 4
diff changeset
133 *O_data = data;
mir3636
parents: 4
diff changeset
134 goto meta(context, next);
mir3636
parents: 4
diff changeset
135 }
mir3636
parents: 4
diff changeset
136
mir3636
parents: 4
diff changeset
137 __code meta(struct Context* context, enum Code next) {
mir3636
parents: 4
diff changeset
138 goto (context->code[next])(context);
mir3636
parents: 4
diff changeset
139 }
mir3636
parents: 4
diff changeset
140
mir3636
parents: 4
diff changeset
141 \end{lstlisting}
mir3636
parents: 4
diff changeset
142
mir3636
parents: 4
diff changeset
143 Gears OS では継続先の Code Gear へと継続する前に Meta Code Gear である
mir3636
parents: 4
diff changeset
144 stub Code Gear へと継続する。
mir3636
parents: 4
diff changeset
145
mir3636
parents: 4
diff changeset
146 stub Code Gear では、継続先が求める Input Code Gear、Output Code Gear を Context から参照している。
mir3636
parents: 4
diff changeset
147 Gearef は Context から Data Gear を参照するためのマクロである。
mir3636
parents: 4
diff changeset
148 stub Code Gear は自動生成されるため、ユーザーレベルでは Context を直接触ることなくプログラミングできる。
mir3636
parents: 4
diff changeset
149
mir3636
parents: 4
diff changeset
150 また、Code Gear は継続の際 meta へと goto する。
mir3636
parents: 4
diff changeset
151 Context はすべての Code Gear のリストを持っており、継続先の Code Gear のアドレスは
mir3636
parents: 4
diff changeset
152 enum で対応付けられた Code Gear のアドレスのリストを参照して継続を行う。
mir3636
parents: 4
diff changeset
153
1
9100f20b8797 copy mitsuki-sigos
mir3636
parents:
diff changeset
154
9100f20b8797 copy mitsuki-sigos
mir3636
parents:
diff changeset
155 Code Gear と Data Gear は Interface と呼ばれるまとまりとして記述される。
9100f20b8797 copy mitsuki-sigos
mir3636
parents:
diff changeset
156 Interface は使用される Data Gear の定義と、それに対する操作を行う Code Gear の集合である。
9100f20b8797 copy mitsuki-sigos
mir3636
parents:
diff changeset
157 Interface 作成時に Code Gear の集合を指定することにより複数の実装を持つことができる。
9100f20b8797 copy mitsuki-sigos
mir3636
parents:
diff changeset
158 Interface の操作に対応する Code Gear の引数は Interface に定義されている Data Gear を通して指定される。
4
mir3636
parents: 3
diff changeset
159 一つの実行スレッド内で使われる Interface の Code Gear と Data Gear は Context に格納される。
1
9100f20b8797 copy mitsuki-sigos
mir3636
parents:
diff changeset
160
5
mir3636
parents: 4
diff changeset
161 Code Gear の継続は関数型プログラミングからみると継続先の Context を含む Closure となっている。
mir3636
parents: 4
diff changeset
162 これを記述するために継続に不定長引数を追加する構文をスクプリトの変換機能として用意した。
mir3636
parents: 4
diff changeset
163 メタ計算側ではこれらの Context を常に持ち歩いているので goto 文で引数を用いることはなく、
mir3636
parents: 4
diff changeset
164 行き先は Code Gear の番号のみで指定される。
1
9100f20b8797 copy mitsuki-sigos
mir3636
parents:
diff changeset
165
9100f20b8797 copy mitsuki-sigos
mir3636
parents:
diff changeset
166 これにより Interface 間の呼び出しを C++ のメソッド呼び出しのように記述することができる。
9100f20b8797 copy mitsuki-sigos
mir3636
parents:
diff changeset
167 Interface の実装は、Context 内に格納されているので、オブジェクトごとに実装を変える多様性を実現できている。
5
mir3636
parents: 4
diff changeset
168
1
9100f20b8797 copy mitsuki-sigos
mir3636
parents:
diff changeset
169
9100f20b8797 copy mitsuki-sigos
mir3636
parents:
diff changeset
170 Context を複製して複数の CPU に割り当てることにより並列実行を可能になる。
9100f20b8797 copy mitsuki-sigos
mir3636
parents:
diff changeset
171 これによりメタ計算として並列処理を記述したことになる。
9100f20b8797 copy mitsuki-sigos
mir3636
parents:
diff changeset
172 Gears のスレッド生成は Agda の関数型プログラミングに対応して行われるのが望ましい。
9100f20b8797 copy mitsuki-sigos
mir3636
parents:
diff changeset
173 そこで、par goto 構文を導入し、Agda の継続呼び出しに対応させることにした。
9100f20b8797 copy mitsuki-sigos
mir3636
parents:
diff changeset
174 par goto では Context の複製、入力の同期、タスクスケジューラーへの Context の登録などが行われる。
9100f20b8797 copy mitsuki-sigos
mir3636
parents:
diff changeset
175 par goto 文の継続として、スレッドの join に相当する \_\_exit を用意した。
9100f20b8797 copy mitsuki-sigos
mir3636
parents:
diff changeset
176 \_\_exit により par goto で分岐した Code Gear の出力を元のスレッドで受け取ることができる。
9100f20b8797 copy mitsuki-sigos
mir3636
parents:
diff changeset
177
9100f20b8797 copy mitsuki-sigos
mir3636
parents:
diff changeset
178 関数型プログラムではメモリ管理は GC などを通して暗黙に行われる。
9100f20b8797 copy mitsuki-sigos
mir3636
parents:
diff changeset
179 Gears OS ではメモリ管理は stub などのメタ計算部分で処理される。
9100f20b8797 copy mitsuki-sigos
mir3636
parents:
diff changeset
180 例えば、寿命の短いスレッドでは使い捨ての線形アロケーションを用いる。
9100f20b8797 copy mitsuki-sigos
mir3636
parents:
diff changeset
181