Mercurial > hg > Papers > 2011 > nobu-prosym
comparison Paper/nobu-prosym.tex~ @ 9:de1193768ef9
modify
author | Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Sat, 19 Nov 2011 18:03:15 +0900 |
parents | 5dfa978ee319 |
children | 3d1f778dc358 |
comparison
equal
deleted
inserted
replaced
7:3d1135b3519c | 9:de1193768ef9 |
---|---|
1 \documentclass[private]{ipsjpapers} | 1 \documentclass[private]{ipsjpapers} |
2 %\documentstyle{ipsjpapers} | 2 %\documentstyle{ipsjpapers} |
3 \usepackage[dvipdfmx]{graphicx} | 3 \usepackage[dvipdfmx]{graphicx} |
4 \usepackage{url} | 4 \usepackage{url} |
5 \usepackage{multirow} %% tabularの上下の結合 | |
6 \usepackage{slashbox} %% tabularでの斜め線 | |
7 \usepackage{listings} | |
8 | |
5 | 9 |
6 % 巻数,号数などの設定 | 10 % 巻数,号数などの設定 |
7 %\setcounter{巻数}{41} | 11 %\setcounter{巻数}{41} |
8 %\setcounter{号数}{6} | 12 %\setcounter{号数}{6} |
9 %\setcounter{volpageoffset}{1234} | 13 %\setcounter{volpageoffset}{1234} |
140 関数と同じように引数を持たせて継続させることもできる. | 144 関数と同じように引数を持たせて継続させることもできる. |
141 しかし,関数とは違ってリターンを行わない為返り値を取得することはできない. | 145 しかし,関数とは違ってリターンを行わない為返り値を取得することはできない. |
142 図\ref{fig:factorial}は CbC で書いたプログラムの例である. | 146 図\ref{fig:factorial}は CbC で書いたプログラムの例である. |
143 与えられた数 x の階上を計算して出力するプログラムとなっている. | 147 与えられた数 x の階上を計算して出力するプログラムとなっている. |
144 | 148 |
145 \begin{figure}[htpb] | 149 \begin{figure} |
146 \begin{center} | 150 \lstinputlisting[language=c]{source/factorial.cbc} |
147 \scalebox{0.40}{\includegraphics{figure/factorial.eps}} | 151 \caption{階上を計算する CbC プログラムの例} |
148 \end{center} | |
149 \caption{階上を計算する CbC プログラムの例} | |
150 \label{fig:factorial} | |
151 \end{figure} | 152 \end{figure} |
152 | 153 |
153 | 154 |
154 %コードセグメントは関数よりも小さな単位で記述される為,最適化がされやすくなる. | 155 %コードセグメントは関数よりも小さな単位で記述される為,最適化がされやすくなる. |
155 %コードセグメントの記述の仕方は C の関数と同じで,引数を持たせて継続を行うことができる. | 156 %コードセグメントの記述の仕方は C の関数と同じで,引数を持たせて継続を行うことができる. |
162 \subsection{3つの内部表現} | 163 \subsection{3つの内部表現} |
163 GCC は内部で Generic Tree, GIMPLE, RTL という3つの内部表現を扱う. | 164 GCC は内部で Generic Tree, GIMPLE, RTL という3つの内部表現を扱う. |
164 それぞれが | 165 それぞれが |
165 読み込んだソースコードは Generic Tree, GIMPLE, RTL の順に変換されていき, | 166 読み込んだソースコードは Generic Tree, GIMPLE, RTL の順に変換されていき, |
166 最後にアセンブラ言語へと出力される. | 167 最後にアセンブラ言語へと出力される. |
167 図\ref{fig:ir}は | 168 図\ref{fig:ir}はアセンブラ出力までの流れを表した図である. |
168 | |
169 | 169 |
170 \begin{figure}[htpb] | 170 \begin{figure}[htpb] |
171 \begin{center} | 171 \begin{center} |
172 \scalebox{0.35}{\includegraphics{figure/ir.eps}} | 172 \scalebox{0.35}{\includegraphics{figure/ir.eps}} |
173 \end{center} | 173 \end{center} |
190 CbC の実装では特に修正は加えていない. | 190 CbC の実装では特に修正は加えていない. |
191 | 191 |
192 | 192 |
193 \subsubsection{Register Transfer Language (RTL)} | 193 \subsubsection{Register Transfer Language (RTL)} |
194 構文木 GIMPLE は解析が行われた後 RTL へと変換される. | 194 構文木 GIMPLE は解析が行われた後 RTL へと変換される. |
195 RTL での表現は低レベルで,アセンブラとほぼ同じ表現を行うことができる. | 195 RTL はレジスタの割り当てといった低レベルの表現で,アセンブラとほぼ同じ表現を行うことができる. |
196 | 196 プログラム内部では RTL も木構造で表される. |
197 | 197 |
198 CbC における継続は,この RTL で行われる最適化の1つ Tail Call Elimination が重要となってくる. | 198 CbC における継続は,この RTL で行われる最適化の1つ Tail Call Elimination が重要となってくる. |
199 | 199 |
200 | 200 |
201 \section{GCC-4.6 への実装} | 201 \section{GCC-4.6 への実装} |
202 前節までで CbC の基本仕様と GCC でのアセンブラ出力までの流れを確認した. | 202 前節までで CbC の基本仕様と GCC でのアセンブラ出力までの流れを確認した. |
203 ここからは GCC-4.6 への実装について述べていく. | 203 ここからは GCC-4.6 への実装について述べていく. |
204 | 204 |
205 | 205 |
206 \subsection{“__code” のパース} | 206 \subsection{“\_\_code” のパース} |
207 | 207 |
208 | 208 |
209 | 209 |
210 \subsection{Tail Call Elimination} | 210 \subsection{Tail Call Elimination} |
211 CbC の継続の実装には GCC の最適化の1つである Tail Call Elimination (末尾除去) が使われる. | 211 CbC の継続の実装には GCC の最適化の1つである Tail Call Elimination (末尾除去) が使われる. |
212 Tail Call Elimination とは関数の最後の処理で別の関数呼び出しを行った際に, | 212 Tail Call Elimination とは関数の最後の処理で別の関数呼び出しを行った際に, |
213 call ではなく jmp を用いることができるという最適化である. | 213 call ではなく jmp を用いることができるという最適化である. |
214 図\ref{continue}は Tail Call Elimination が行われた際のプログラムの処理を表している. | 214 図\ref{fig:continue}は Tail Call Elimination が行われた際のプログラムの処理を表している. |
215 | 215 |
216 | 216 |
217 \begin{figure}[htpb] | 217 \begin{figure}[htpb] |
218 \begin{center} | 218 \begin{center} |
219 \scalebox{0.50}{\includegraphics{figure/continuation.eps}} | 219 \scalebox{0.50}{\includegraphics{figure/continuation.eps}} |
223 \end{figure} | 223 \end{figure} |
224 funcB の処理の最後に呼ばれた funcC は,返り値を funcB ではなく funcA へと返す. | 224 funcB の処理の最後に呼ばれた funcC は,返り値を funcB ではなく funcA へと返す. |
225 | 225 |
226 | 226 |
227 \subsubsection{expand\_call} | 227 \subsubsection{expand\_call} |
228 ある関数が Tail Call Elimination を行えるかどうかは expand\_call 関数によって判断される. | 228 ある関数が Tail Call Elimination を行えるかどうかは expand\_call 関数で判断される. |
229 Tail call Elimination が行える場合 try\_tail_call | 229 expand\_call 関数内でチェックされる Tail Call Elimination が行える条件は以下になる. |
230 expand\_call 関数の中で try_tail_call というフラグ | 230 |
231 \begin{itemize} | |
232 \item caller 側と callee 側の返す値の型が一致している. | |
233 \item 関数呼び出しがリターンの直前に行われている. | |
234 \item 呼出先関数の引数に用いられるスタックサイズが呼出元関数のそれより少ない. | |
235 \item[] | |
236 \end{itemize} | |
237 | |
238 | |
239 CbC の実装では上記の条件を,以下の様にして解決させている. | |
240 | |
241 \begin{itemize} | |
242 \item 呼び出す関数がコードセグメントの場合返す値の型チェックを行わない. | |
243 \item コードセグメントへの継続を Generic Tree で表す際に,return の情報も直後に持たせる. | |
244 \item スタックサイズは決め打ちで行う. | |
245 \item[] | |
246 \end{itemize} | |
247 | |
248 スタックサイズを決め打ちで行うことで,ベースポインタを変えずにスタックを扱うことができる. | |
249 これも CbC の1つの特徴である. | |
250 図\ref{fig:cs_stack}はコードセグメントの継続の際にスタックに積まれる引数を表している. | |
251 | |
252 | |
253 \begin{figure}[htpb] | |
254 \begin{center} | |
255 \scalebox{0.33}{\includegraphics{figure/cs_stack.eps}} | |
256 \end{center} | |
257 \caption{継続による引数のスタック格納の様子} | |
258 \label{fig:cs_stack} | |
259 \end{figure} | |
260 | |
261 | |
262 %expand\call 関数では Tail Call Elimination が可能かどうかを判断するために,try\_tail\_call フラグが用意されている. | |
263 %Tail call Elimination が行えないと判断されると try\_tail\_call フラグに0がセットされる. | |
264 | |
265 | |
266 expand\_call 関数の中で try\_tail\_call フラグ | |
231 | 267 |
232 | 268 |
233 | 269 |
234 \subsection{引数渡し} | 270 \subsection{引数渡し} |
235 通常コードセグメントの継続において,引数は C の関数と同じスタックを用いて渡される. | 271 通常コードセグメントの継続において,引数は C の関数と同じスタックを用いて渡される. |
236 GCC には引数渡しをスタックではなくレジスタを用いて行う機能として fastcall がある. | 272 GCC には引数渡しをスタックではなくレジスタを用いて行う機能として fastcall がある. |
237 fastcall を用いてコードセグメントを宣言することで,レジスタを用いた速度の向上を図る. | 273 fastcall を用いてコードセグメントを宣言することで,レジスタを用いた速度の向上を図る. |
274 | |
238 | 275 |
239 \subsubsection{fastcall} | 276 \subsubsection{fastcall} |
240 コードセグメントの引数渡しを fastcall によりできるだけレジスタを用いて行うようにする. | 277 コードセグメントの引数渡しを fastcall によりできるだけレジスタを用いて行うようにする. |
241 C において fastcall を用いる場合は関数にキーワード “\_\_attribute\_\_ ((fastcall))” をつけて行う. | 278 C において fastcall を用いる場合は関数にキーワード “\_\_attribute\_\_ ((fastcall))” をつけて行う. |
242 だが,コードセグメントを全てこのキーワードをつけて宣言することは実用できではない. | 279 だが,コードセグメントを全てこのキーワードをつけて宣言することは実用できではない. |
243 そこで,コードセグメントで宣言された場合,fastcall が自動で付くように実装を行う. | 280 そこで,コードセグメントで宣言された場合,fastcall が自動で付くように実装を行う. |
244 図\ref{fig:fastcall}はコードセグメントに fastcall 属性を付与しているソースである. | 281 図\ref{fig:fastcall}はコードセグメントに fastcall 属性を付与しているソースである. |
245 | 282 |
246 \begin{figure}[htpb] | 283 %\lstinputlisting[language=c]{source/fastcall.c} |
247 \begin{center} | 284 |
248 \scalebox{0.35}{\includegraphics{figure/fastcall.eps}} | 285 \begin{figure}[htpb] |
249 \end{center} | 286 \begin{center} |
250 \caption{fastcall属性付与} | 287 \scalebox{0.33}{\includegraphics{figure/fastcall.eps}} |
288 \end{center} | |
289 \caption{コードセグメントへのfastcall属性付与} | |
251 \label{fig:fastcall} | 290 \label{fig:fastcall} |
252 \end{figure} | 291 \end{figure} |
253 | 292 |
254 if 文で条件を決めているのは,64 bit の場合 fastcall が標準で行われ為である. | 293 |
255 | 294 if 文で条件を決めているのは,64 bit の場合 fastcall が標準で行われ, |
256 | 295 fastcall 属性を付けると warning を出すからである. |
257 \begin{thebibliography}{10} | 296 |
297 | |
298 \section{評価} | |
299 今回実装を行った GCC-4.6 ベースのコンパイラを GCC-4.4 ベース, | |
300 Micro-C コンパイラとそれぞれ比較を行った. | |
301 比較を行うのはクイックソートのプログラムである. | |
302 クイックソートは再帰的にプログラムされる為 CbC に向いている | |
303 プログラムだと言える. | |
304 比較を行うのは以下のアーキテクチャと OS になる. | |
305 | |
306 %\begin{description} | |
307 \begin{itemize} | |
308 \item x86/Linux | |
309 \item x86/OS X | |
310 \end{itemize} | |
311 %\end{description} | |
312 | |
313 また,比較を行うプログラムは最適化(-O0 オプション)を行わないものと, | |
314 速度最適化(-O2 -fomit-frame-pointer)を行うものの2つ, | |
315 それと -m32 オプションと -m64 オプションをつけたものそれぞれで行う. | |
316 | |
317 表\ref{tab:speed-mc-vs-gcc-nonopt}が最適化無し, | |
318 表\ref{tab:speed-mc-vs-gcc-opt}が速度最適化有りとなる. | |
319 | |
320 \begin{table}[htpb] | |
321 \centering | |
322 \small | |
323 \begin{tabular}{|c|c|c|c|} \hline | |
324 CPU/OS &GCC-4.4& GCC-4.6 &Micro-C \\ \hline | |
325 x86/Linux & 7.378 & 0.829 & 2.890 \\ \hline | |
326 x86\_64/OS X(-m32)& 3.890 & 0.382 & 2.288 \\ \hline | |
327 x86\_64/OS X & 4.078 & 0.450 & \\ \hline | |
328 \end{tabular} | |
329 \caption{アーキテクチャ毎のGCCとmicro-cの速度比較(単位: 秒)(最適化無し)} | |
330 \label{tab:speed-mc-vs-gcc-nonopt} | |
331 \end{table} | |
332 | |
333 | |
334 \begin{table}[htpb] | |
335 \centering | |
336 \small | |
337 \begin{tabular}{|c|c|c|c|} \hline | |
338 CPU/OS &GCC-4.4& GCC-4.6 &Micro-C \\ \hline | |
339 x86/Linux & 3.252 & 2.906 & 2.890 \\ \hline | |
340 x86\_64/OS X(-m32)& 1.827 & 0.934 & 2.288 \\ \hline | |
341 x86\_64/OS X & 1.101 & 2.896 & \\ \hline | |
342 \end{tabular} | |
343 \caption{アーキテクチャ毎のGCCとmicro-cの速度比較(単位: 秒)(速度最適化)} | |
344 \label{tab:speed-mc-vs-gcc-opt} | |
345 \end{table} | |
346 | |
347 | |
348 | |
349 \begin{thebibliography}{7} | |
258 | 350 |
259 \bibitem{1}{河野真治}: | 351 \bibitem{1}{河野真治}: |
260 “継続を基本とした言語 CbC の gcc 上の実装”. 日本ソフトウェア科学会第 19 回大会論文集, Sep, 2002 | 352 “継続を基本とした言語 CbC の gcc 上の実装”. 日本ソフトウェア科学会第 19 回大会論文集, Sep, 2002 |
261 | 353 |
354 | |
262 \bibitem{2}{河野真治}: | 355 \bibitem{2}{河野真治}: |
263 “継続を持つ C の回言語によるシステム記述”. 日本ソフトウェア科学会第 17 回大会論文集, Sep, 2000 | 356 “継続を持つ C の回言語によるシステム記述”. 日本ソフトウェア科学会第 17 回大会論文集, Sep, 2000 |
264 | 357 |
265 \bibitem{3}{与儀健人,河野真治}: | 358 \bibitem{3}{与儀健人,河野真治}: |
266 “Continuation based CコンパイラのGCC-4.2による実装”. 琉球大学 情報工学科 学位論文, 2008 | 359 “Continuation based CコンパイラのGCC-4.2による実装”. 琉球大学 情報工学科 学位論文, 2008 |