comparison Paper/anatofuz.tex @ 28:f200e3702c5a

update register info
author Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
date Fri, 09 Nov 2018 01:56:17 +0900
parents df723be56106
children 765dc5c49ae1
comparison
equal deleted inserted replaced
27:df723be56106 28:f200e3702c5a
167 Rakudoにおけるコンパイラとは厳密には2種類存在する. 167 Rakudoにおけるコンパイラとは厳密には2種類存在する.
168 まず第1のものがPerl6,もしくはNQPをMoarVM,JVMのバイトコードに変換するNQPコンパイラである. 168 まず第1のものがPerl6,もしくはNQPをMoarVM,JVMのバイトコードに変換するNQPコンパイラである.
169 次にそのNQPが出力したバイトコードをネイティブコードに変換するVMの2種類である. 169 次にそのNQPが出力したバイトコードをネイティブコードに変換するVMの2種類である.
170 このVMは現在MoarVM,JavaVM,Javascriptを選択可能である. 170 このVMは現在MoarVM,JavaVM,Javascriptを選択可能である.
171 Rakudo及びNQP projectではこのNQPコンパイラの部分をフロントエンド,VMの部分をバックエンド\cite{rani1}と呼称している. 171 Rakudo及びNQP projectではこのNQPコンパイラの部分をフロントエンド,VMの部分をバックエンド\cite{rani1}と呼称している.
172 NQPで主に書かれたPerl6のことをRakudoと呼ぶ. 172 NQPで主に書かれ,MoarVMなどNQPが動作する環境で動くPerl6のことをRakudoと呼ぶ.
173 Perl6はNQP以外にもPerl6独自の一種のシンタックスシュガーの様な物を持っており,これはNQPコンパイラ側で処理を行う. 173 Perl6はNQP以外にものNQPを拡張したPerl6自身で書かれている箇所が存在し,これはNQPコンパイラ側でMoarVMが解釈可能な形へ変換を行う.
174 174
175 \begin{figure}[ht] 175 \begin{figure}[ht]
176 \begin{center} 176 \begin{center}
177 \includegraphics[width=70mm]{fig/perl6nqp.pdf} 177 \includegraphics[width=70mm]{fig/perl6nqp.pdf}
178 \end{center} 178 \end{center}
262 そのため対象となるCodeSegmentをLABLESの並びと対応させ,配列CODESに設定すればCodeSegmentの名前は問わない. 262 そのため対象となるCodeSegmentをLABLESの並びと対応させ,配列CODESに設定すればCodeSegmentの名前は問わない.
263 今回はCodeSegmentである事を示す為にsuffixとしてcbc\_をつける. 263 今回はCodeSegmentである事を示す為にsuffixとしてcbc\_をつける.
264 264
265 命令の実行処理でMoarVMのレジスタであるreg\_baseや命令列cur\_opなどの情報を利用しているが,これらはMVM\_interp\_run内のローカル変数として利用している. 265 命令の実行処理でMoarVMのレジスタであるreg\_baseや命令列cur\_opなどの情報を利用しているが,これらはMVM\_interp\_run内のローカル変数として利用している.
266 ラベルを利用しているオリジナル版では同一関数内であるためアクセス可能であるが,CodeSegment間の移動で命令を表現するCbCではアクセスできない. 266 ラベルを利用しているオリジナル版では同一関数内であるためアクセス可能であるが,CodeSegment間の移動で命令を表現するCbCではアクセスできない.
267 その為インタプリタの情報を集約した構造体interを定義し,この構造体へのポインタであるINTERP型の変数iをCodeSegmentの入出力して与える. 267 その為インタプリタの情報を集約した構造体interを定義し,この構造体へのポインタであるINTERP型の変数iをCodeSegmentの入出力として与える.
268 CodeSegment内ではINTERPを経由することでインタプリタの各種情報にアクセスする. 268 CodeSegment内ではINTERPを経由することでインタプリタの各種情報にアクセスする.
269 CodeSegment間の遷移ではレジスタの値の調整は行われない為,入力引数を使ってレジスタマッピングを管理できる.
270 その為INTERPのメンバであるMoarVMのレジスタそのものをアーキテクチャのレジスタ上に乗せる事が可能である.
269 271
270 命令実行中のCodeSegmentの遷移を図\ref{fig:perl6cbcinter}に示す. 272 命令実行中のCodeSegmentの遷移を図\ref{fig:perl6cbcinter}に示す.
271 この中で実線で書かれている部分はCbCのgoto文で遷移し,波線の箇所は通常のCの関数呼び出しとなっている. 273 この中で実線で書かれている部分はCbCのgoto文で遷移し,波線の箇所は通常のCの関数呼び出しとなっている.
272 274
273 現在のCbCMoarVMは次の命令セットのディスパッチをcbc\_nextというCodeSegmentで処理している. 275 現在のCbCMoarVMは次の命令セットのディスパッチをcbc\_nextというCodeSegmentで処理している.
286 \end{figure} 288 \end{figure}
287 289
288 現在CbCで記述されたOSであるGearsOSにはInterfaceが導入されている. 290 現在CbCで記述されたOSであるGearsOSにはInterfaceが導入されている.
289 これはJavaのinterface,Haskellの型クラスに該当する概念であり,次のCodeSegmentにInterface経由で継続する事が可能である. 291 これはJavaのinterface,Haskellの型クラスに該当する概念であり,次のCodeSegmentにInterface経由で継続する事が可能である.
290 Interfaceは現在のMoarVMには実装されていない為,今後ThreadeCodeの実装を行うにあたり導入を検討している. 292 Interfaceは現在のMoarVMには実装されていない為,今後ThreadeCodeの実装を行うにあたり導入を検討している.
293
294 \subsection{Threaded Code}
295 現在のMoarVMは次の命令をバイトコードからディスパッチし決定後,ラベルジャンプを利用し実行している.
296 この処理ではディスパッチの箇所にコストが掛かってしまう.
297 CbCをMoarVMに導入することで,バイトコード列を直接サブルーチンコールの列に置き換えてしまう事が可能である.
298 これはCbCが基本ブロックの単位と対応している為である.
299 また段階的に現在8バイト列を1命令コードとして使用しているが,これを16バイトなどに拡張し2命令を同時に扱えるように実装する事なども可能である.
300
301 %CbCはCodeSegmentで末尾最適化(Tail call optimization)を行う.
302 %これはCodeSegmentは必ず関数呼び出しではなくgotoで次の状態に遷移する為にスタック領域の操作が必要とならない為である.
303 %現在のCbCコンパイラの実装ではCodeSegmentからCの関数に戻る場合は末尾最適化を切り,CodeSegment間の遷移では末尾最適化が行われる.
304 %末尾最適化を応用することでContinuation-passingスタイルのThreaded Codeの実装が可能となる.\cite{threadedcode}
305 %またCodeSegment自体を直接次の遷移先として設定することも可能であるため,CbCならThrededCodeを実装するアプローチが複数検討出来る.
306
307 %現在のCbCMoarVMは次の命令セットのディスパッチをcbc\_nextというCodeSegmentで処理している.
308 %これは元のMoarVMの命令ディスパッチで行われる現在のオペコードを示すcur\_opと命令列opの操作及び次のラベルに遷移するマクロに該当する.
309 %CbCMoarVMではラベルに対しての遷移の代わりにMoarVMの命令のCodeSegmentの集合体である配列CODESにアクセスし,その要素であるCodeSegmentに対して遷移する形を取っている.
310 %この一連の処理がオーバーヘッドになる為,今後はcbc\_fixt\_nextというCodeSegmentを導入し直接次の命令に該当するCodeSegmentへgotoする様に実装する予定である.
311
312 \subsubsection{perlcc}
313 Perl5においてはperlccというモジュールが開発されている.
314 これはPerl5内部で利用しているPerlバイトコードを,PerlのC APIであるXS言語の様なCのソースファイルに埋め込み,それをCコンパイルでコンパイルするというものである.
315 perlccを利用することでPerlインタプリタが無い状況でも可動するバイナリファイルを作成する事が可能である.
316 しかしPerlccはPerlスクリプトが複雑になるほど正確にCに移植を行う事が出来ず,現在ではPerlのコアモジュールから外されている.
317 PerlccはPerlのバイトコードをCへの変換のみ行う為,Cで実装されているPerl経由で実行した場合と処理速度はほぼ変わらない.
318 またPerlccで生成されたCのソースコードは難解であり,これをデバッグするのが困難でもある.
319 MoarVMでthreaded codeを実現出来た場合,その箇所のみCbCプログラムとして切り出す事が可能である為perlccと似たツールを作成することも可能である.
320 この場合,Perl6を通常動かした際とは異なりバイトコードインタプリタに到達する前の処理が無くなる為多少の高速化が望めると推測できる.
291 321
292 \subsection{MoarVMのBytecodeのデバッグ} 322 \subsection{MoarVMのBytecodeのデバッグ}
293 moarに対してmoarvm bytecodeをdumpオプションを付けて読み込ませるとmoarvmのbytecodeがアセンブラの様に出力される. 323 moarに対してmoarvm bytecodeをdumpオプションを付けて読み込ませるとmoarvmのbytecodeがアセンブラの様に出力される.
294 しかしこれはmoarvmが実行したbytecodeのトレースではなくmoarvm bytecodeを変換したものに過ぎない. 324 しかしこれはmoarvmが実行したbytecodeのトレースではなくmoarvm bytecodeを変換したものに過ぎない.
295 また,明らかに異なる挙動を示す両者のmoarを利用しても同じ結果が返ってきてしまう. 325 また,明らかに異なる挙動を示す両者のmoarを利用しても同じ結果が返ってきてしまう.
330 このバグは先程の並列デバッグを行いながらプログラムカウンタや変数の動きをトレースする事などで発見することが出来る. 360 このバグは先程の並列デバッグを行いながらプログラムカウンタや変数の動きをトレースする事などで発見することが出来る.
331 現状ではCbCコンパイラがプログラマの意図と反する挙動を取るためCbCコンパイラのバグを回避するプログラミングが要求されている. 361 現状ではCbCコンパイラがプログラマの意図と反する挙動を取るためCbCコンパイラのバグを回避するプログラミングが要求されている.
332 本来コンパイラ側のバグを回避するプログラミングをプログラマに要求する事は好ましくない. 362 本来コンパイラ側のバグを回避するプログラミングをプログラマに要求する事は好ましくない.
333 従ってCbCコンパイラ自身の信頼性を向上させる事も今後の課題となっている. 363 従ってCbCコンパイラ自身の信頼性を向上させる事も今後の課題となっている.
334 364
335 また現在はclang上に実装したCbCコンパイラではtaill call除去のエラーが発生してしまう為コンパイルする事が出来ない. 365 また現在はclang上に実装したCbCコンパイラではCodeSegment内部のtaill call除去のエラーが発生してしまう為コンパイルする事が出来ない.
336 その為現在はgcc上に実装したcbcコンパイラを利用しgdbを利用しデバッグを行う. 366 その為現在はgcc上に実装したcbcコンパイラを利用しgdbを利用しデバッグを行う.
337 \subsection{Threaded Code} 367
338 CbCはCodeSegmentで末尾最適化(Tail call optimization)を行う.
339 これはCodeSegmentは必ず関数呼び出しではなくgotoで次の状態に遷移する為にスタック領域の操作が必要とならない為である.
340 現在のCbCコンパイラの実装ではCodeSegmentからCの関数に戻る場合は末尾最適化を切り,CodeSegment間の遷移では末尾最適化が行われる.
341 末尾最適化を応用することでContinuation-passingスタイルのThreaded Codeの実装が可能となる.\cite{threadedcode}
342 またCodeSegment自体を直接次の遷移先として設定することも可能であるため,CbCならThrededCodeを実装するアプローチが複数検討出来る.
343
344 %現在のCbCMoarVMは次の命令セットのディスパッチをcbc\_nextというCodeSegmentで処理している.
345 %これは元のMoarVMの命令ディスパッチで行われる現在のオペコードを示すcur\_opと命令列opの操作及び次のラベルに遷移するマクロに該当する.
346 %CbCMoarVMではラベルに対しての遷移の代わりにMoarVMの命令のCodeSegmentの集合体である配列CODESにアクセスし,その要素であるCodeSegmentに対して遷移する形を取っている.
347 この一連の処理がオーバーヘッドになる為,今後はcbc\_fixt\_nextというCodeSegmentを導入し直接次の命令に該当するCodeSegmentへgotoする様に実装する予定である.
348
349 \subsubsection{perlcc}
350 Perl5においてはperlccというモジュールが開発されている.
351 これはPerl5内部で利用しているPerlバイトコードを,PerlのC APIであるXS言語の様なCのソースファイルに埋め込み,それをCコンパイルでコンパイルするというものである.
352 perlccを利用することでPerlインタプリタが無い状況でも可動するバイナリファイルを作成する事が可能である.
353 しかしPerlccはPerlスクリプトが複雑になるほど正確にCに移植を行う事が出来ず,現在ではPerlのコアモジュールから外されている.
354 PerlccはPerlのバイトコードをCへの変換のみ行う為,Cで実装されているPerl経由で実行した場合と処理速度はほぼ変わらない.
355 またPerlccで生成されたCのソースコードは難解であり,これをデバッグするのが困難でもある.
356 MoarVMでthreaded codeを実現出来た場合,その箇所のみCbCプログラムとして切り出す事が可能である為perlccと似たツールを作成することも可能である.
357 この場合,Perl6を通常動かした際とは異なりバイトコードインタプリタに到達する前の処理が無くなる為多少の高速化が望めると推測できる.
358 368
359 \section{CbCを用いる事についての利点と欠点} 369 \section{CbCを用いる事についての利点と欠点}
360 MoarVMの様な巨大なスクリプト言語処理系にCbCを適応した所現在までに複数の利点と欠点が発見された. 370 MoarVMの様な巨大なスクリプト言語処理系にCbCを適応した所現在までに複数の利点と欠点が発見された.
361 本章ではまず利点を述べ,次に現段階でのCbCを適応した場合の欠点について考察する. 371 本章ではまず利点を述べ,次に現段階でのCbCを適応した場合の欠点について考察する.
362 372