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