comparison cbc.tex @ 0:e9ecd5b5f29a

first commit.
author kent <kent@cr.ie.u-ryukyu.ac.jp>
date Fri, 29 Jan 2010 15:45:41 +0900
parents
children aa09c34b90d3
comparison
equal deleted inserted replaced
-1:000000000000 0:e9ecd5b5f29a
1 \chapter{Continuation based C (CbC)}
2 \label{chp:cbc}
3 Continuation based C(以下CbC)は当研究室の提案する、アセンブラよりも上位でCよりも下位な記述言語である。
4 我々は\ref{chp:first}章に述べたように様々な視点からこのCbCを使った研究を行っている。
5 本章ではそのCbCの仕様について説明する。
6
7
8 \section{CbCの要求仕様}
9 90 年代以降、ハードウェアの進歩がプログラミング言語よりも早く進みつつ
10 あり、70 年代、80 年代に設計された言語は矛盾を抱えて来ている。
11
12 オブジェクト指向技術とそれに基づいたJava などの言語が注目されているが
13 、これらの言語は動的な適合性を中心に設計されたものである。C などの低レ
14 ベルな言語による記述に比べて、余分な条件判断(Method search, Meta level
15 での実行) を増やしてしまい、コンパクトで高速な応答を期待される
16 Real-time 処理や組み込み用途には適さない。
17
18 ハードウェアに一番近い言語はアセンブラであるがマクロアセンブラなどの記
19 述はあまりにも低レベルであり、長年進歩していない。しかし使用可能なゲー
20 ト数が増えるにつれ、RISC 的な対称性の高い小数の命令よりも、複雑なマル
21 チメディア関係の命令などを持つCISC 的なCPU が増えてきている。そのため
22 に既存の言語に対するコンパイラを一々設計し直すことが必要になってきてい
23 る。
24
25 VHDL, Verilog などのハードウェア記述言語は有限状態遷移の中に閉じており
26 、オブジェクト指向などの抽象化とはまったく別なものとなってしまっている。
27
28 このように3 つは全く異なる方向を向いている。コンパイラの自動生成などが
29 重要な研究テーマとなると考えられるが、ハードウェア記述言語、アセンブラ
30 、プログラミング言語の3 つが全く独立したものであれば困難なものになると
31 考えられる。
32
33 そこでCbC はこの3 つを埋めるべく以下のような要求仕様に従って設計された。
34 \begin{itemize}
35 \item ハードウェアとスタックマシンの中間言語
36
37 インタプリタ記述やコンパイラターゲットとして優れること。アーキテク
38 チャ依存性が少ないこと、また、アーキテクチャ依存性をモデル化できる。
39
40 \item C 言語よりも下位の言語
41
42 アセンブラよりも汎用性と記述性に優れC と互換であること。C をCbC に
43 コンパイルでき、ハンドコンパイルの結果を同値なコードに変換できる。
44
45 \item 明確な実行モデル
46
47 C++やProlog のような複雑な実行モデルは好ましくなく、ハードウェアに
48 実行順序の変更を許す範囲を広くする。
49
50 \item 状態遷移を直接記述できる
51
52 Yacc のような表駆動やC のような巨大なswitch 文ではなく直接に状態遷
53 移ができ実行できる。
54
55 \item Thread を実行モデルに内蔵できる
56
57 並列処理記述法ではなく状態遷移として表現できる。
58
59 \item クリティカルパスの最適化
60
61 全体を散漫に最適化するコンパイルではなくクリティカルパスを見つけ出
62 して最適化できる。
63 \end{itemize}
64
65 これらの仕様はハードウェア記述とソフトウェア記述の両方を同時に行いつつ
66 、C よりも精密な実行記述を可能にするためのものである。また、CbC はプロ
67 グラム変換やコンパイラターゲットとして使うことを意識している。状態遷移
68 記述のみでは制御機構は静的なものになってしまう。CbC では状態遷移記述に
69 適した言語を作ることを考え、スタックマシンを避けてContinuation(継続)
70 が導入されている。
71
72
73 \section{コードセグメントと継続}
74
75 \subsection{call-returnから継続制御へ}
76 Cなどの一般的な手続き型言語では、呼び出した手続きの処理のあと、呼出し
77 元の環境に復帰する。そのためプログラム全体においてスタックが用意され、
78 呼出し元はスタックに復帰先アドレス及び環境を保持しておく事で呼出し先か
79 らの復帰を可能とする。これはcall-return制御と呼ばれるものである(図
80 \ref{fig:call-return})。
81 しかし復帰先さえ決まっていれば、このcall-return制御は図
82 \ref{fig:continuation}の様に手続き呼び出しの前後で分割する事ができ、環
83 境の保持を伴わないシーケンシャルな呼び出しに変換する事ができる。
84 これは継続制御構造と呼ばれている。schemeのcall-with-continuationの実装
85 や、 Java,C++の例外処理、Cのsetjmp()/longjmp()による大域脱出もこの継続
86 制御の一種である。
87 \begin{figure}[hptb]
88 \begin{center}
89 %\includegraphics[width=\textwidth,bb=0 0 595 842]{figures/call-return.pdf}
90 \includegraphics[width=.6\textwidth]{figures/call-return.eps}
91 \end{center}
92 \caption{call-return制御}
93 \label{fig:call-return}
94 \end{figure}
95 \begin{figure}[hptb]
96 \begin{center}
97 \includegraphics[width=.6\textwidth]{figures/continuation.eps}
98 \end{center}
99 \caption{継続制御}
100 \label{fig:continuation}
101 \end{figure}
102
103 CbCはこの継続制御を基本として設計されており、その実現のためにコードセ
104 グメントと軽量継続という概念を用いている。
105 以下ではその二つについて説明する。
106
107 \subsection{コードセグメント}
108 CbCは図\ref{fig:continuation}の様に分割された手続きのそれぞれを一つの
109 処理単位として用い、これを``コードセグメント''(code-segment)と呼ぶ。
110
111 コードセグメントはキーワード``code''を用いてCの関数の様に定義される。
112 例として引数で与えられた数xの階乗を求めるプログラムをコード
113 \ref{code:factorial}に示した。
114 引数部分はインタフェイスと呼ばれ、継続前のコードセグメントからの出力に
115 あたる。
116
117 %コードセグメントは手続きを細かく分割したものなので、Cの関数と比べより
118 %小さい処理単位となる。しかしコードセグメント内部ではCのステートメント
119 %と同様の記述が可能であり、処理単位としてはステートメントより大きいもの
120 %となる。
121
122 \subsection{軽量継続(light-weight continuation)}
123 コードセグメントはCにおける関数とは違い、呼出し元への復帰は存在しない。
124 そのためコードセグメントの処理の末尾で別のコードセグメントへ継続するこ
125 とになる。CbCではこの継続制御を``軽量継続''(light-weight continuation)
126 と呼ぶ。
127
128 軽量継続はキーワード``goto''のあとにコードセグメント名とそのコードセグ
129 メントのインタフェイスに渡す引数列を並べて記述する。(同じく軽量継続の
130 例がコード \ref{code:factorial}にみられる。)
131
132
133 %この引数列は継続前のコードセグメントの状態、つまりインタフェイスの値に
134 %よって一意に決まる
135
136 \lstinputlisting[caption=コードセグメント例(階乗計算),label=code:factorial]{sources/factorial.cbc}
137
138
139 \section{状態遷移に適した言語}
140 Continuation based Cは値を返すプログラムよりも、状態遷移記述に適している。
141
142 従来の言語での状態遷移記述は
143 \begin{itemize}
144 \item 表を使った状態遷移インタプリタ
145 \item 巨大なswitch文
146 \end{itemize}
147 などが用いられてきた。しかしこれらは記述性が悪く、効率も良くない。
148
149 表を使った状態遷移インタプリタはコンパイラ言語とは考えられない。また、
150 それをハードウェア記述に落とすことは難しい。
151
152 巨大なswitch文は、コンパイルが複雑になり、適切な最適化を行うことが難し
153 い。また、人間が読む場合にも読みやすいとは言えない。
154
155 CbCは元々状態遷移を直接記述することを目的として設計されており、
156 手続きの様に環境の保持を伴わないため、その時々に実行中のコードセグメン
157 トとその引数を直接プログラムの状態とみなす事ができる。
158
159 特にゲームやGUIを用いたプログラムなどでは状態遷移記述が多用されており
160 、そのようなプログラムでは CbCを状態記述言語として使うことにより、直接
161 実行による実行の高速化と既存の言語と状態遷移記述の整合性の向上をはかる
162 ことができる。
163
164
165 \section{C with Continuation}
166 \ref{chp:purp}でも述べたようにCbCはCと互換性を持つことが望ましい。
167 CbCをCと相互に利用するためには、Cの関数から継続を行った場合に元の環境
168 に戻るための、特殊な継続を導入する必要がある。これを環境付き継続と呼ぶ。
169
170 この環境付き継続を導入した言語はC with Continuation(CwC)と呼ばれ、Cと
171 CbCの両方の機能をもつ言語となる。また、 C、CbCはCwCのサブセットと考え
172 られるので(図 \ref{fig:cwc})、CwCのコンパイラをCbCに使用する事ができ
173 る。これまでに実装されてきたCbCのコンパイラは1章で説明したmicro-c、gcc
174 、共に厳密にはCwCのコンパイラである。すなわち、Cの関数やforなどを使う
175 ことができ、mcでは環境付き継続も実装されている。
176
177 \begin{figure}[htpb]
178 \begin{center}
179 \includegraphics[width=.6\textwidth]{figures/CwC.eps}
180 \end{center}
181 \caption{C with Continuationとそのサブセット}
182 \label{fig:cwc}
183 \end{figure}
184
185
186 \subsection{環境付き継続}
187 環境付き継続を用いる場合、Cの関数からコードセグメントへ継続する際に
188 \_\_returnという名前で表される特殊なコードセグメントポインタを渡す。コ
189 ード\ref{}参照。
190 継続先のコードセグメントでは渡されたコードセグメントポインタへ継続する
191 事で元のCの環境に復帰することが可能となる。
192 ただし復帰先は\_\_returnを参照した関数が終了する位置である。
193
194 \lstinputlisting[
195 caption=\_\_returnの例,
196 label=code:return-example]
197 {sources/return-example.cbc}
198
199
200
201
202 %CbCにおける環境付き継続の構文は幾度か改訂されている。
203 % TODO _CbC_return
204
205
206 \section{gccベースコンパイラの現時点の問題点}
207
208
209 当初CbCのコンパイラはmicro-cをベースとしたものが使われていた。しかしよ
210 り多くのアーキテクチャや最適化機能などの要望により、 2008年の研究をも
211 って\ref{}GCCによる実装が行われた。この研究によりコードセグメント、継
212 続制御構造などは実装され、一通りのCbCプログラムのコンパイルが可能とな
213 った。
214
215 しかし、前節に説明した環境付き継続はまだ実装に至っておらず、また継続制
216 御構造の実装方法の影響により、いくつかの問題が発生している。
217 以下にその問題点を列記する。
218 %この問題に対せる解決を \ref{chp:impl}章にて説明する。
219
220
221 \begin{itemize}
222 \item 環境付き継続
223
224 これは未実装の機能である。
225 変更された新しい仕様の方に対応したい。
226
227 \item 並列代入
228
229 CbCでは現在のコードセグメントのインタフェイスと次に継続するコード
230 セグメントの引数は同じメモリスペース(もしくはレジスタ)に格納してい
231 る。そのためコード\ref{code:paralell_example}のように変数の値を入
232 れ替えるような処理では並列代入が行われることになる。
233 前実装では単純な並列代入に対しては問題がなかったが、構造体の混じる
234 複雑な並列代入ではバグが見つかっている。
235 \lstinputlisting[
236 caption=並列代入の例,
237 label=code:parallel-example]
238 {sources/parallel-example.cbc}
239
240 \item PowerPCにおける間接継続(indirect goto)
241
242 CbCで用いる継続制御は、Cでの関数ポインタを用いた間接呼び出し
243 (indirect call)の様にコードセグメントポインタを用いた間接継続が可
244 能である。
245 \lstinputlisting[
246 caption=間接継続の例(2つめのgoto文),
247 label=code:indirect-example]
248 {sources/indirect-example.cbc}
249 しかしPowerPCアーキテクチャでは最適化の問題でこの機能が働かないこ
250 とが分かっている。
251
252 \item プロトタイプ宣言
253
254 Cのプロトタイプ宣言はコンパイル時のエラー検出に役立っている。
255 しかしCbCのコードセグメントには返り値は存在しない。また状態遷移記
256 述という性質上、プログラムを記述する際は上から下に実行順にコードセ
257 グメントを並べることが多いため、プロトタイプ宣言をするとそれが膨大
258 な数になる。
259
260 \item x86での継続制御のオーバヘッド
261
262 mc実装ではx86アーキテクチャでのコードセグメント継続の際には引数を
263 レジスタに格納していた。しかしx86では、Cの関数呼び出しはデフォルト
264 では全ての引数をメモリに格納する。コードセグメントは関数をベースに
265 作られているため、このABIに引きずられ実効速度に影響をもたらす。
266
267
268 \end{itemize}
269
270