annotate final_main/chapter2.tex @ 6:5b368e14bb64

update
author mir3636
date Tue, 14 Feb 2017 18:48:26 +0900
parents 6d00f6c9bb8a
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
30a433a94a9a first commit
mir3636
parents:
diff changeset
1 \chapter{Continuation based C (CbC)}
30a433a94a9a first commit
mir3636
parents:
diff changeset
2 \section{Continuation based C (CbC)}
30a433a94a9a first commit
mir3636
parents:
diff changeset
3 CbC は 処理を Code Gear とした単位を用いて記述するプログラミング言語である。
6
mir3636
parents: 4
diff changeset
4 Code Gear は入力と出力を持ち、CbC では引数が入出力となっている。
mir3636
parents: 4
diff changeset
5 Code Gear から次の Code Gear へと goto による継続で遷移で処理を行い、引数として出力を与える。
0
30a433a94a9a first commit
mir3636
parents:
diff changeset
6 図\ref{fig:cs}は Code Gear 間の処理の流れを表している。
30a433a94a9a first commit
mir3636
parents:
diff changeset
7
30a433a94a9a first commit
mir3636
parents:
diff changeset
8 \begin{figure}[htpb]
30a433a94a9a first commit
mir3636
parents:
diff changeset
9 \begin{center}
30a433a94a9a first commit
mir3636
parents:
diff changeset
10 \scalebox{0.7}{\includegraphics{fig/codesegment.pdf}}
30a433a94a9a first commit
mir3636
parents:
diff changeset
11 \end{center}
30a433a94a9a first commit
mir3636
parents:
diff changeset
12 \caption{goto による code gear 間の継続}
30a433a94a9a first commit
mir3636
parents:
diff changeset
13 \label{fig:cs}
30a433a94a9a first commit
mir3636
parents:
diff changeset
14 \end{figure}
30a433a94a9a first commit
mir3636
parents:
diff changeset
15
30a433a94a9a first commit
mir3636
parents:
diff changeset
16 \section{Code Gear}
30a433a94a9a first commit
mir3636
parents:
diff changeset
17 Code Gear は CbC における最も基本的な処理単位である。
30a433a94a9a first commit
mir3636
parents:
diff changeset
18 リスト \ref{code_simple} は最も基本的な CbC のコードの一例で、図 \ref{fig:code_simple}はそれを図示したものである。
30a433a94a9a first commit
mir3636
parents:
diff changeset
19 CbC では Code Gear は \_\_code という型を持つ関数の構文で定義される。
6
mir3636
parents: 4
diff changeset
20 ただし、これは \_\_code 型の戻り値を返すという意味ではなく、Code Gear であることを示すフラグのようなものである。
mir3636
parents: 4
diff changeset
21
4
mir3636
parents: 0
diff changeset
22 Code Gear は戻り値を持たないので、関数とは異なり return 文は存在しない。
mir3636
parents: 0
diff changeset
23 goto の後に Code Gear 名と引数を並べて、次の Code Gear の遷移を記述する。
6
mir3636
parents: 4
diff changeset
24 リスト \ref{code_simple} の goto cs1(a+b); などがこれにたる。
mir3636
parents: 4
diff changeset
25 この goto の行き先を継続と呼び、このときの a+b が次の Code Gear への出力となる。
4
mir3636
parents: 0
diff changeset
26 Scheme の継続と異なり CbC には呼び出し元の環境がないので、この継続は単なる行き先である。
mir3636
parents: 0
diff changeset
27 したがってこれを軽量継続と呼ぶこともある。
0
30a433a94a9a first commit
mir3636
parents:
diff changeset
28 軽量継続により、並列化、ループ制御、関数コールとスタックの操作を意識した最適化がソースコードレベルで行えるようにする。
30a433a94a9a first commit
mir3636
parents:
diff changeset
29
30a433a94a9a first commit
mir3636
parents:
diff changeset
30 \begin{lstlisting}[frame=lrbt,label=code_simple,caption={\footnotesize code segment の軽量継続}]
30a433a94a9a first commit
mir3636
parents:
diff changeset
31 __code cs0(int a, int b){
30a433a94a9a first commit
mir3636
parents:
diff changeset
32 goto cs1(a+b);
30a433a94a9a first commit
mir3636
parents:
diff changeset
33 }
30a433a94a9a first commit
mir3636
parents:
diff changeset
34
30a433a94a9a first commit
mir3636
parents:
diff changeset
35 __code cs1(int c){
30a433a94a9a first commit
mir3636
parents:
diff changeset
36 goto cs2(c);
30a433a94a9a first commit
mir3636
parents:
diff changeset
37 }
30a433a94a9a first commit
mir3636
parents:
diff changeset
38 \end{lstlisting}
30a433a94a9a first commit
mir3636
parents:
diff changeset
39
30a433a94a9a first commit
mir3636
parents:
diff changeset
40 \begin{figure}[htpb]
30a433a94a9a first commit
mir3636
parents:
diff changeset
41 \begin{center}
30a433a94a9a first commit
mir3636
parents:
diff changeset
42 \scalebox{0.55}{\includegraphics{fig/codesegment2.pdf}}
30a433a94a9a first commit
mir3636
parents:
diff changeset
43 \end{center}
30a433a94a9a first commit
mir3636
parents:
diff changeset
44 \caption{code segment の軽量継続}
30a433a94a9a first commit
mir3636
parents:
diff changeset
45 \label{fig:code_simple}
30a433a94a9a first commit
mir3636
parents:
diff changeset
46 \end{figure}
30a433a94a9a first commit
mir3636
parents:
diff changeset
47
4
mir3636
parents: 0
diff changeset
48 もう少し複雑な CbC のプログラムの例が以下のリスト \ref{factorial} である。
mir3636
parents: 0
diff changeset
49 これは与えられた数値の階乗を算出するプログラムである。
mir3636
parents: 0
diff changeset
50 このコードの factorial0 という Code Gear に注目すると、条件判別を行い、その結果に応じて自分自身への再帰的な継続を行うか別の Code Gear への継続を行うかという処理を行っていることがわかる。
mir3636
parents: 0
diff changeset
51 CbC ではこのようにしてループ処理を制御する。
mir3636
parents: 0
diff changeset
52
mir3636
parents: 0
diff changeset
53 \begin{lstlisting}[frame=lrbt,label=factorial,caption={\footnotesize 階乗を求める CbC プログラムの例}]
mir3636
parents: 0
diff changeset
54 __code print_factorial(int prod)
mir3636
parents: 0
diff changeset
55 {
mir3636
parents: 0
diff changeset
56 printf("factorial = %d\n",prod);
mir3636
parents: 0
diff changeset
57 exit(0);
mir3636
parents: 0
diff changeset
58 }
mir3636
parents: 0
diff changeset
59
mir3636
parents: 0
diff changeset
60 __code factorial0(int prod, int x)
mir3636
parents: 0
diff changeset
61 {
mir3636
parents: 0
diff changeset
62 if ( x >= 1) {
mir3636
parents: 0
diff changeset
63 goto factorial0(prod*x, x-1);
mir3636
parents: 0
diff changeset
64 }else{
mir3636
parents: 0
diff changeset
65 goto print_factorial(prod);
mir3636
parents: 0
diff changeset
66 }
mir3636
parents: 0
diff changeset
67
mir3636
parents: 0
diff changeset
68 }
mir3636
parents: 0
diff changeset
69
mir3636
parents: 0
diff changeset
70 __code factorial(int x)
mir3636
parents: 0
diff changeset
71 {
mir3636
parents: 0
diff changeset
72 goto factorial0(1, x);
mir3636
parents: 0
diff changeset
73 }
mir3636
parents: 0
diff changeset
74
mir3636
parents: 0
diff changeset
75 int main(int argc, char **argv)
mir3636
parents: 0
diff changeset
76 {
mir3636
parents: 0
diff changeset
77 int i;
mir3636
parents: 0
diff changeset
78 i = atoi(argv[1]);
mir3636
parents: 0
diff changeset
79
mir3636
parents: 0
diff changeset
80 goto factorial(i);
mir3636
parents: 0
diff changeset
81 }
mir3636
parents: 0
diff changeset
82 \end{lstlisting}
mir3636
parents: 0
diff changeset
83
6
mir3636
parents: 4
diff changeset
84 \begin{figure}[htpb]
mir3636
parents: 4
diff changeset
85 \begin{center}
mir3636
parents: 4
diff changeset
86 \scalebox{0.55}{\includegraphics{fig/factorial.pdf}}
mir3636
parents: 4
diff changeset
87 \end{center}
mir3636
parents: 4
diff changeset
88 \caption{階乗を求める CbC プログラムの軽量継続図}
mir3636
parents: 4
diff changeset
89 \label{fig:factorial}
mir3636
parents: 4
diff changeset
90 \end{figure}
mir3636
parents: 4
diff changeset
91
0
30a433a94a9a first commit
mir3636
parents:
diff changeset
92 \section{環境付き継続}
30a433a94a9a first commit
mir3636
parents:
diff changeset
93 環境付き継続は C との互換性のために必要な機能である。
30a433a94a9a first commit
mir3636
parents:
diff changeset
94 CbC と C の記述を交える際、CbC の Code Gear から C の関数の呼び出しは問題なく行える。
30a433a94a9a first commit
mir3636
parents:
diff changeset
95 しかし、C の関数から CbC の Code Gear へと継続する場合、呼び出し元の環境に戻るための特殊な継続が必要となる。
30a433a94a9a first commit
mir3636
parents:
diff changeset
96 これを環境付き継続と呼ぶ。
30a433a94a9a first commit
mir3636
parents:
diff changeset
97
30a433a94a9a first commit
mir3636
parents:
diff changeset
98 環境付き継続を用いる場合、C の関数から Code Gear へ継続する際に \_\_ return、\_\_environment という変数を渡す。
30a433a94a9a first commit
mir3636
parents:
diff changeset
99 \_\_return は \_\_code (*)(return\_type, void*) 型の変数で環境付き継続先が元の環境に戻る際に利用する Code Gear を表す。
30a433a94a9a first commit
mir3636
parents:
diff changeset
100 \_\_environment は void** 型の変数で元の関数の環境を表す。
30a433a94a9a first commit
mir3636
parents:
diff changeset
101 リスト\ref{gotoWithTheEnv}では関数 funcB から Code Gear cs に継続する際に環境付き継続を利用している。
30a433a94a9a first commit
mir3636
parents:
diff changeset
102 cs は funcB から渡された Code Gear へ継続することで元の C の環境に復帰することが可能となる。
30a433a94a9a first commit
mir3636
parents:
diff changeset
103 但し復帰先は \_\_return を渡した関数が終了する位置である。
30a433a94a9a first commit
mir3636
parents:
diff changeset
104 このプログラムの例では、関数 funcA は戻り値として funcB の終わりにある -1 ではなく、環境付き継続によって渡される 1 を受け取る。
30a433a94a9a first commit
mir3636
parents:
diff changeset
105 図\ref{fig:gotoWithTheEnv}にこの様子を表した。
30a433a94a9a first commit
mir3636
parents:
diff changeset
106
30a433a94a9a first commit
mir3636
parents:
diff changeset
107 \begin{lstlisting}[frame=lrbt,label=gotoWithTheEnv,caption={環境付き継続}]
30a433a94a9a first commit
mir3636
parents:
diff changeset
108 __code cs(__code (*ret)(int, void*), void *env){
30a433a94a9a first commit
mir3636
parents:
diff changeset
109 /* C0 */
30a433a94a9a first commit
mir3636
parents:
diff changeset
110 goto ret(1, env);
30a433a94a9a first commit
mir3636
parents:
diff changeset
111 }
30a433a94a9a first commit
mir3636
parents:
diff changeset
112
30a433a94a9a first commit
mir3636
parents:
diff changeset
113 int funcB(){
30a433a94a9a first commit
mir3636
parents:
diff changeset
114 /* B0 */
30a433a94a9a first commit
mir3636
parents:
diff changeset
115 goto cs(__return, __environment);
30a433a94a9a first commit
mir3636
parents:
diff changeset
116 /* B1 (never reached). */
30a433a94a9a first commit
mir3636
parents:
diff changeset
117 return -1;
30a433a94a9a first commit
mir3636
parents:
diff changeset
118 }
30a433a94a9a first commit
mir3636
parents:
diff changeset
119
30a433a94a9a first commit
mir3636
parents:
diff changeset
120 int funcA(){
30a433a94a9a first commit
mir3636
parents:
diff changeset
121 /* A0 */
30a433a94a9a first commit
mir3636
parents:
diff changeset
122 int retval;
30a433a94a9a first commit
mir3636
parents:
diff changeset
123 retval = funcB();
30a433a94a9a first commit
mir3636
parents:
diff changeset
124 /* A1 */
30a433a94a9a first commit
mir3636
parents:
diff changeset
125 printf("retval = %d\n", retval);
30a433a94a9a first commit
mir3636
parents:
diff changeset
126 /* retval should not be -1 but be 1. */
30a433a94a9a first commit
mir3636
parents:
diff changeset
127 return 0;
30a433a94a9a first commit
mir3636
parents:
diff changeset
128 }
30a433a94a9a first commit
mir3636
parents:
diff changeset
129
30a433a94a9a first commit
mir3636
parents:
diff changeset
130 \end{lstlisting}
30a433a94a9a first commit
mir3636
parents:
diff changeset
131
30a433a94a9a first commit
mir3636
parents:
diff changeset
132 \begin{figure}[htpb]
30a433a94a9a first commit
mir3636
parents:
diff changeset
133 \begin{center}
30a433a94a9a first commit
mir3636
parents:
diff changeset
134 \scalebox{0.55}{\includegraphics{fig/gotowithenv.pdf}}
30a433a94a9a first commit
mir3636
parents:
diff changeset
135 \end{center}
30a433a94a9a first commit
mir3636
parents:
diff changeset
136 \caption{環境付き継続}
30a433a94a9a first commit
mir3636
parents:
diff changeset
137 \label{fig:gotoWithTheEnv}
30a433a94a9a first commit
mir3636
parents:
diff changeset
138 \end{figure}
30a433a94a9a first commit
mir3636
parents:
diff changeset
139
30a433a94a9a first commit
mir3636
parents:
diff changeset
140 このように、環境付き継続を用いることで C、CbC 間の処理の移動が可能になる。
30a433a94a9a first commit
mir3636
parents:
diff changeset
141
30a433a94a9a first commit
mir3636
parents:
diff changeset
142 %Data Gear はデータの単位であり、int や文字列などの Primitive Type を持っている。
30a433a94a9a first commit
mir3636
parents:
diff changeset
143
30a433a94a9a first commit
mir3636
parents:
diff changeset
144 %Code Gear は 任意の数の Input Data Gear を参照して処理を行い、Output Data Gear を出力し処理を終える。
30a433a94a9a first commit
mir3636
parents:
diff changeset
145 %また、接続された Data Gear 以外には参照を行わない。
30a433a94a9a first commit
mir3636
parents:
diff changeset
146
30a433a94a9a first commit
mir3636
parents:
diff changeset
147 %処理やデータの構造が Code Gear、Data Gear に閉じているため、これにより実行時間、メモリ使用量などを予測可能なものにすることが可能になる。
30a433a94a9a first commit
mir3636
parents:
diff changeset
148