Mercurial > hg > Papers > 2008 > kono-ieice-vld
view 4.tex @ 0:685b35adf419
Initial revision
author | kono |
---|---|
date | Thu, 06 Mar 2008 19:49:25 +0900 |
parents | |
children |
line wrap: on
line source
\section{ Continuation based C} CbC (Continuation based C)は、Cからサブルーチンやループ構造 を除いたCの下位言語であり、ハードウェアとソフトウェア、特に 組込みシステムの記述言語として本研究室で提案している言語で ある。 Cの関数の代わりに、 たコード・ セグメントという単位を持つ。コードセグメントには、入口に相当する Input interface と、出口に相当するParameterized goto 文が存在する。 \begin{figure}[htb] \begin{center} \includegraphics[width=6cm]{fig/code.eps} \end{center} \label{fig000} \end{figure} 以下は簡単なCbCのプログラムである。 {\small \begin{verbatim} code fact(int n,int result, code print()){ if(n>0){ result *= n; n--; goto fact(n,result,print); } else goto (*print)(result); } \end{verbatim} } 間接gotoと、直接gotoが、プログラムの単位の結び付きをボトムアップに 規定して、自然なグループを構成する。 CbCの継続は、Schemeなどの継続とは異なり環境(関数の呼び出し履歴)を持たない。 コードセグメントは、関数呼び出しではないので環境を持つ必要がない。 Cにコードセグメントと引数つきgoto文を付加したCwCは、Cのスーパセット であり、 コードセグメント内から通常のCの関数を呼び出すことも可能ある。また、 通常の関数からコードセグメントへgotoしたり、コードセグメントから、 呼び出された関数へ値を戻すことも出来る。 コードセグメントは状態遷移記述と対応しているので、ハードウェア記述 とも相性が良い。 CbCコンパイラは、micro-C base のものと GCC base, TCC base のものが 動いており、実用的に使うことができる。{\tt sourceforge.jp} 上\cite{cbc-sourceforge}で公開されている。 \subsection{ CからCbCへの変換} Cのスタックを明示的に構成することによりCのプログラムをCbCに 変換することが可能である。 {\small \begin{verbatim} j = g(i+3); \end{verbatim} } のようなCの関数呼び出しは、 \verb+struct f_g0_save+ などの 明示的なスタックの中身を表す構造体を用いて、 {\small \begin{verbatim} struct f_g0_interface *c = (struct f_g0_save *)(sp -= sizeof(struct f_g0_save)); c = sp; c->ret = f_g1; goto g(i+3,sp); \end{verbatim} } のような形で、明示的なスタック操作に変換される。これは変換の 一例であり、他の方法、例えばリンクトリストなどを用いても良い。 \verb+f_g1+ は、関数呼び出しの後の継続であり、\verb+g+ では、 {\small \begin{verbatim} code g(int i,stack sp) { goto (* ((struct f_g0_save *)sp)->ret) (i+4,sp); } \end{verbatim} } のように間接的に呼び出される。スタックの中は、継続と 中間変数などを格納する構造体である。スタックそのものは、 これらの構造体を格納するメモリである。 これらの変換は自動的に行うことが出来き、試作変換系を実装した 報告\cite{kono01g}もあるが、実用レベルの変換系はまだ存在しない。 現在は変換と、その後の最適化はは手動で行う必要がある。 \subsection{ CbCでの並列実行記述} 並列実行記述ではタスクの生成と同期機構の記述が問題になる。Verilog やVHDLなどでも並列タスクの記述があり、POSIX Thread ではライブラリ コールとして\verb+pthread_create+や\verb+pthread_mutex_lock+などが ある。 これらの動作記述は、マニュアルやFormal Description で示されている。 例えば、以下のような記述である。 {\tt The pthread\_mutex\_lock() function locks mutex. If the mutex is already locked, the calling thread will block until the mutex becomes available. } このようは記述は曖昧で誤解を招きやすい。しかし、同期機構の検証 では、これらの動作の正確な意味を知る必要がある。 CbC ではad-hoc な並列記述プリミティブは必要ではなく、自分自身で 並列実行を記述することが可能である。これは、コードセグメントには 隠された情報が存在しないので、実行に必要な情報をすべてInput interface から取得できるからである。 実行キューを作成しCbC自体でSchedulerを記述することにより、 並列実行を記述する。この場合の並列実行単位はコードセグメン トとなる。goto 文を規則的にscheduler へのgoto文に書き換える ことにより、並列実行を記述することが出来る。 以下は、CbCで記述した Dining Philosopher の状態の一部である。 {\small \begin{verbatim} code pickup_rfork(PhilsPtr self) { if (self->right_fork->owner == NULL) { self->right_fork->owner = self; goto eating(self); } else { goto hungry2(self); } } \end{verbatim} } これを並列実行するためには、 {\small \begin{verbatim} code pickup_rfork(PhilsPtr self, TaskPtr current_task) { if (self->right_fork->owner == NULL) { self->right_fork->owner = self; self->next = eating; goto scheduler(self, current_task); } else { self->next = hungry2; goto scheduler(self, current_task); } } \end{verbatim} } という形に記述を変える。Scheduler の実装は例えば、FIFOであれば、 {\small \begin{verbatim} code scheduler(PhilsPtr self, TaskPtr list) { TaskPtr t = list; TaskPtr e; list = list->next; goto list->phils->next(list->phils,list); } \end{verbatim} } という形になる。このように自分自身で並列実行スケジューラを 記述できることがCbCの特徴である。同期機構であるが、ここでは \verb+right_fork+の排他制御は、 コードセグメントが同時に実行されることはないので、自動的に 保証されている。条件付変数のような待ち合わせを実現したい場合は、 TaskPtr への操作として実現すれば良い。 \subsection{ CbCでの並列実行の実装} FIFO scheduler を例えば Cell のSPUのactive task queue への 挿入とし、active task queue を各SPUが自律的に取得するように する(SPU scheduler)と、実際にCbCのコードセグメントを並列実 行することが出来る。 FIFO schedulerと実際の並列実行の同期機構が一致するようにする のは、一般的には自明ではない。同期機構をコードセグメントで記述 して、SPU scheduler によって実現しても良いし、コードセグメント 内部で、例えば、\verb+pthread_mutex_lock+を呼び出しても良い。