Mercurial > hg > Papers > 2019 > anatofuz-prosym
comparison Slide/slide.html @ 88:632f160ccbd0
update
author | Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Thu, 10 Jan 2019 21:55:46 +0900 |
parents | 2c38abf2c77d |
children | 1f9baa69dfe0 |
comparison
equal
deleted
inserted
replaced
87:67510e8dea72 | 88:632f160ccbd0 |
---|---|
92 | 92 |
93 <!-- _S9SLIDE_ --> | 93 <!-- _S9SLIDE_ --> |
94 <h2 id="研究目的">研究目的</h2> | 94 <h2 id="研究目的">研究目的</h2> |
95 <ul> | 95 <ul> |
96 <li>スクリプト言語であるPerl5の後継言語としてPerl6が現在開発されている.</li> | 96 <li>スクリプト言語であるPerl5の後継言語としてPerl6が現在開発されている.</li> |
97 <li>現在主流なPerl6はRakudoと言われるプロジェクトである.</li> | 97 <li>現在主流なPerl6の実装にRakudoがあり, RakudoはNQP(Perl6のサブセット)で記述されたPerl6, NQPで記述されたNQPコンパイラがある</li> |
98 <li>RakudoではPerl6自体をNQP(NotQuitPerl)と言われるPerl6のサブセットで記述し, NQPをVMが解釈するという処理の流れになっている.</li> | 98 <li>NQPコンパイラはRakudoのVMであるMoarVM用のバイトコードを生成し, MoarVMはこのバイトコードを解釈, 実行する</li> |
99 <li>主に利用されているVMに, Cで書かれたMoarVMが存在する.</li> | 99 <li>Continuation based C (CbC)という言語は継続を基本とするC言語であり, 言語処理系に応用出来ると考えられる</li> |
100 <li>MoarVMは全体的な起動時間及び処理速度が, Perl5と比較し非常に低速である.</li> | 100 <li>CbC一部用いてMoarVMの書き換えを行い, 処理を検討する.</li> |
101 <li>この問題を解決するためにContinuation based C (CbC)という言語を一部用いてMoarVMの書き換えを行う.</li> | |
102 <li>CbCを用いたMoarVMの書き換えを検討し,並列デバッグ方法などについて検討する.</li> | |
103 </ul> | 101 </ul> |
104 | 102 |
105 | 103 |
106 | 104 |
107 </div> | 105 </div> |
109 <div class='slide'> | 107 <div class='slide'> |
110 <!-- _S9SLIDE_ --> | 108 <!-- _S9SLIDE_ --> |
111 <h2 id="continuation-based-c-cbc">Continuation Based C (CbC)</h2> | 109 <h2 id="continuation-based-c-cbc">Continuation Based C (CbC)</h2> |
112 | 110 |
113 <ul> | 111 <ul> |
114 <li>Continuation Based C (CbC) はCodeGearとDataGearを単位として用いたプログラミング言語である.</li> | 112 <li>Continuation Based C (CbC) はCodeGearを単位として用いたプログラミング言語である.</li> |
115 <li>CodeGearはCの通常の関数呼び出しとは異なり,スタックに値を積まず, 次のCodeGearにgoto文によって遷移する.</li> | 113 <li>CodeGearはCの通常の関数呼び出しとは異なり,スタックに値を積まず, 次のCodeGearにgoto文によって遷移する.</li> |
116 <li>このgoto文による遷移を軽量継続と呼ぶ.</li> | 114 <li>このgoto文による遷移を軽量継続と呼ぶ.</li> |
117 <li>CbCは軽量継続を取り入れたCの下位言語であり, C言語のAPIを利用可能なCと互換性のある言語である.</li> | |
118 </ul> | |
119 | |
120 | |
121 | |
122 </div> | |
123 | |
124 <div class='slide'> | |
125 <!-- _S9SLIDE_ --> | |
126 <h2 id="codegearとdetagear">CodeGearとDetaGear</h2> | |
127 | |
128 <ul> | |
129 <li>Cの関数の代わりにCodeGearという単位をCbCでは導入している.</li> | |
130 <li>CodeGearはCの関数宣言の型名の代わりに<code>__code</code>と書く事で宣言出来る.</li> | 115 <li>CodeGearはCの関数宣言の型名の代わりに<code>__code</code>と書く事で宣言出来る.</li> |
131 <li>CodeGearの引数を遷移先のCodeGearと揃えることでレジスタに変数を確保した状態で軽量継続可能である.</li> | |
132 <li>その為CodeGearの引数は入出力としての意味があり, DataGearと呼んでいる.</li> | |
133 </ul> | 116 </ul> |
134 | 117 |
135 <pre><code>extern int printf(const char*,...); | 118 <pre><code>extern int printf(const char*,...); |
136 int main (){ | 119 int main (){ |
137 int data = 0; | 120 int data = 0; |
154 <div class='slide'> | 137 <div class='slide'> |
155 <!-- _S9SLIDE_ --> | 138 <!-- _S9SLIDE_ --> |
156 <h2 id="cbcの現在の実装">CbCの現在の実装</h2> | 139 <h2 id="cbcの現在の実装">CbCの現在の実装</h2> |
157 | 140 |
158 <ul> | 141 <ul> |
159 <li>CbCは現在2種類の実装がある. | 142 <li>CbCは現在3種類の実装がある. |
160 <ul> | 143 <ul> |
161 <li>gcc (version 9.0.0)</li> | 144 <li>gcc (version 9.0.0)</li> |
162 <li>llvm/clang (version 7.0.0)</li> | 145 <li>llvm/clang (version 7.0.0)</li> |
146 <li>micro-c</li> | |
163 </ul> | 147 </ul> |
164 </li> | 148 </li> |
165 </ul> | 149 </ul> |
166 | 150 |
167 | 151 |
170 | 154 |
171 <div class='slide'> | 155 <div class='slide'> |
172 <!-- _S9SLIDE_ --> | 156 <!-- _S9SLIDE_ --> |
173 <h2 id="言語処理系の応用">言語処理系の応用</h2> | 157 <h2 id="言語処理系の応用">言語処理系の応用</h2> |
174 <ul> | 158 <ul> |
175 <li>CbCではCodeGearを処理単位として利用でき, これはコンパイラの基本ブロックに相当する.</li> | 159 <li>スクリプト言語処理系は, バイトコードにコンパイルされ, バイトコードをJITを用いてネイティブに変換する</li> |
176 <li>従来のスクリプト言語などの処理系では, 主にcase文で実装していた命令コードディスパッチの箇所をCodeGearの遷移として記述する事が可能である.</li> | 160 <li>JITを使わない場合, バイトコードに対応した, case文や, ラベルのテーブルにgotoすることで処理を実行する</li> |
177 <li>CodeGearの遷移として記述する事で, 命令処理ごとに分割する事が可能となり, モジュール化が可能となる.</li> | 161 <li>CbCを言語処理系に応用した場合, バイトコードに対応するCodeGearを生成することが可能である</li> |
178 <li>CodeGearとCodeGearの遷移時に入出力のインターフェイスを揃える事で, レジスタに変数が割り振られたまま軽量継続が可能となり, レジスタレベルの最適化が可能となる.</li> | 162 <li>バイトコードに対応したCodeGearは, CodeGearのテーブルを経由することで実行出来る</li> |
179 <li>これらの検証とPerl6の高速化を行う為に, CbCを用いてPerl6処理系の書き換えを行っていく.</li> | 163 <li>CodeGearに分割することで, 処理を複数の関数で記述する事が出来, ファイル分割などのモジュール化が可能となる</li> |
180 </ul> | |
181 | |
182 | |
183 | |
184 </div> | |
185 | |
186 <div class='slide'> | |
187 <!-- _S9SLIDE_ --> | |
188 <h2 id="perl6の概要">Perl6の概要</h2> | |
189 | |
190 <ul> | |
191 <li>Perl6とはPerl5の後継言語として当初開発が開始された言語である.</li> | |
192 <li>仕様と実装が分離しており, 仕様は公式テストスーツであるRoastそのものとなっている.</li> | |
193 <li>歴史的にHaskellで実装されたPugs, Pythonとの共同基盤を目指したParrotなどの実装が存在する.</li> | |
194 <li>言語仕様としては漸進的型付け言語であり, 従来のPerl5とは互換性が無い.</li> | |
195 <li>現在の主要な実装はRakudoと呼ばれる実装である.</li> | |
196 </ul> | 164 </ul> |
197 | 165 |
198 | 166 |
199 | 167 |
200 </div> | 168 </div> |
203 <!-- _S9SLIDE_ --> | 171 <!-- _S9SLIDE_ --> |
204 <h2 id="rakudo">Rakudo</h2> | 172 <h2 id="rakudo">Rakudo</h2> |
205 <ul> | 173 <ul> |
206 <li>Rakudoとは現在のPerl6の主力な実装である.</li> | 174 <li>Rakudoとは現在のPerl6の主力な実装である.</li> |
207 <li>実行環境のVM, Perl6のサブセットであるNQP(NotQuitPerl), NQPで記述されたPerl6(Rakudo)という構成になっている.</li> | 175 <li>実行環境のVM, Perl6のサブセットであるNQP(NotQuitPerl), NQPで記述されたPerl6(Rakudo)という構成になっている.</li> |
208 <li>VMはCで書かれたPerl6専用のVMであるMoarVM, JavaVMが選択可能である.</li> | 176 <li> |
177 コンパイラは, NQPで記述されたPerl6コンパイラ, NQPで記述されたNQPコンパイラ, MoarVMバイトコードを解釈するMoarVMという構成である | |
178 </li> | |
209 <li>現在はMoarVMがRakudoの中でも主流なVM実装となっている.</li> | 179 <li>現在はMoarVMがRakudoの中でも主流なVM実装となっている.</li> |
210 </ul> | |
211 | |
212 | |
213 | |
214 </div> | |
215 | |
216 <div class='slide'> | |
217 <!-- _S9SLIDE_ --> | |
218 <h2 id="rakudo-1">Rakudo</h2> | |
219 <ul> | |
220 <li>Rakudoにおけるコンパイラは2種類存在する | |
221 <ul> | |
222 <li>Perl6やNQPのコードをVMのバイトコードに変換するコンパイラ</li> | |
223 <li>NQPが出力したVMのバイトコードをネイティブコードに変換するコンパイラ</li> | |
224 </ul> | |
225 </li> | |
226 <li>NQPの処理系nqp及び, Perl6のインタプリタである perl6は, それぞれセルフコンパイルしたものを利用する</li> | |
227 <li>Perl6は純粋なNQPではなく, Perl6自身によって拡張され記述されている箇所も存在する</li> | |
228 </ul> | 180 </ul> |
229 | 181 |
230 | 182 |
231 | 183 |
232 </div> | 184 </div> |
246 </div> | 198 </div> |
247 | 199 |
248 <div class='slide'> | 200 <div class='slide'> |
249 <!-- _S9SLIDE_ --> | 201 <!-- _S9SLIDE_ --> |
250 <h2 id="mvm_interp_run">MVM_interp_run</h2> | 202 <h2 id="mvm_interp_run">MVM_interp_run</h2> |
203 | |
204 <ul> | |
205 <li>DISPATCHマクロは次の様に記述されており, この中の <code>OP</code> で宣言されたブロックがそれぞれオペコードに対応する処理となっている.</li> | |
206 <li>この中では <code>GET_REG</code> などのマクロを用いてMoarVMのレジスタにアクセスする.</li> | |
207 <li><code>cur_op</code>は次のオペコード列が登録されており, マクロ <code>NEXT</code> で決められた方法で次のオペコードに遷移する.</li> | |
208 </ul> | |
209 | |
210 <pre><code>DISPATCH(NEXT_OP) { | |
211 OP(const_i64): | |
212 GET_REG(cur_op, 0).i64 = MVM_BC_get_I64(cur_op, 2); | |
213 cur_op += 10; | |
214 goto NEXT; | |
215 } | |
216 | |
217 </code></pre> | |
218 | |
219 | |
220 | |
221 </div> | |
222 | |
223 <div class='slide'> | |
224 <!-- _S9SLIDE_ --> | |
225 <h2 id="mvm_interp_run-1">MVM_interp_run</h2> | |
251 | 226 |
252 <ul> | 227 <ul> |
253 <li>MVM_interp_runでは次のオペコードをフェッチする際に <code>NEXT_OP</code> マクロを介して計算を行う.</li> | 228 <li>MVM_interp_runでは次のオペコードをフェッチする際に <code>NEXT_OP</code> マクロを介して計算を行う.</li> |
254 <li>オペコードが対応する命令を実行する際は, <code>MVM_CGOTO</code> フラグが立っている場合はCのラベルgotoを利用し, 使えない場合はswitch文を利用して遷移する.</li> | 229 <li>オペコードが対応する命令を実行する際は, <code>MVM_CGOTO</code> フラグが立っている場合はCのラベルgotoを利用し, 使えない場合はswitch文を利用して遷移する.</li> |
255 </ul> | 230 </ul> |
271 | 246 |
272 </div> | 247 </div> |
273 | 248 |
274 <div class='slide'> | 249 <div class='slide'> |
275 <!-- _S9SLIDE_ --> | 250 <!-- _S9SLIDE_ --> |
276 <h2 id="mvm_interp_run-1">MVM_interp_run</h2> | 251 <h2 id="mvm_interp_run-2">MVM_interp_run</h2> |
277 | 252 |
278 <ul> | 253 <ul> |
279 <li>ラベル遷移を利用する場合は配列<code>LABELS</code>にアクセスし, ラベル情報を取得する</li> | 254 <li>ラベル遷移を利用する場合は配列<code>LABELS</code>にアクセスし, ラベル情報を取得する</li> |
280 </ul> | 255 </ul> |
281 | 256 |
300 | 275 |
301 </div> | 276 </div> |
302 | 277 |
303 <div class='slide'> | 278 <div class='slide'> |
304 <!-- _S9SLIDE_ --> | 279 <!-- _S9SLIDE_ --> |
305 <h2 id="mvm_interp_run-2">MVM_interp_run</h2> | |
306 | |
307 <ul> | |
308 <li>DISPATCHマクロは次の様に記述されており, この中の <code>OP</code> で宣言されたブロックがそれぞれオペコードに対応する処理となっている.</li> | |
309 <li>この中では <code>GET_REG</code> などのマクロを用いてMoarVMのレジスタにアクセスする.</li> | |
310 <li><code>cur_op</code>は次のオペコードを意味し, マクロ <code>NEXT</code> で決められた方法で次のオペコードに遷移する.</li> | |
311 </ul> | |
312 | |
313 <pre><code>DISPATCH(NEXT_OP) { | |
314 OP(no_op): | |
315 goto NEXT; | |
316 OP(const_i8): | |
317 OP(const_i16): | |
318 OP(const_i32): | |
319 MVM_exception_throw_adhoc(tc, "const_iX NYI"); | |
320 OP(const_i64): | |
321 GET_REG(cur_op, 0).i64 = MVM_BC_get_I64(cur_op, 2); | |
322 cur_op += 10; | |
323 goto NEXT; | |
324 OP(pushcompsc): { | |
325 MVMObject * const sc = GET_REG(cur_op, 0).o; | |
326 if (REPR(sc)->ID != MVM_REPR_ID_SCRef) | |
327 MVM_exception_throw_adhoc(tc, "Can only push an SCRef with pushcompsc"); | |
328 if (MVM_is_null(tc, tc->compiling_scs)) { | |
329 MVMROOT(tc, sc, { | |
330 tc->compiling_scs = MVM_repr_alloc_init(tc, tc->instance->boot_types.BOOTArray); | |
331 }); | |
332 } | |
333 MVM_repr_unshift_o(tc, tc->compiling_scs, sc); | |
334 cur_op += 2; | |
335 goto NEXT; | |
336 } | |
337 } | |
338 | |
339 </code></pre> | |
340 | |
341 | |
342 | |
343 </div> | |
344 | |
345 <div class='slide'> | |
346 <!-- _S9SLIDE_ --> | |
347 <h2 id="mvm_interp_run-3">MVM_interp_run</h2> | 280 <h2 id="mvm_interp_run-3">MVM_interp_run</h2> |
348 | 281 |
349 <ul> | 282 <ul> |
350 <li>Cの実装の場合, switch文に展開される可能性がある為, 命令ディスパッチが書かれているCソース・ファイルの指定の場所にのみ処理を記述せざるを得ない | 283 <li>Cの実装の場合, switch文に展開される可能性がある為, 命令ディスパッチが書かれているCソース・ファイルの指定の場所にのみ処理を記述せざるを得ない |
351 <ul> | 284 <ul> |
352 <li>その為, 1ファイルあたりの記述量が膨大になり, 命令のモジュール化ができない</li> | 285 <li>その為, 1ファイルあたりの記述量が膨大になり, 命令のモジュール化ができない</li> |
353 </ul> | 286 </ul> |
354 </li> | 287 </li> |
355 <li>Threaded Codeの実装を考えた場合, この命令に対応して大幅に処理系の実装を変更する必要がある.</li> | 288 <li>Threaded Codeの実装を考えた場合, この命令に対応して大幅に処理系の実装を変更する必要がある.</li> |
356 <li>デバッグ時には今どの命令を実行しているか, ラベルテーブルを利用して参照せざるを得ず, 手間がかかる.</li> | 289 <li>デバッグ時には今どの命令を実行しているか, ラベルテーブルを利用して参照せざるを得ず, 手間がかかる.</li> |
357 </ul> | |
358 | |
359 | |
360 | |
361 </div> | |
362 | |
363 <div class='slide'> | |
364 <!-- _S9SLIDE_ --> | |
365 <h2 id="nqp">NQP</h2> | |
366 <ul> | |
367 <li>MoarVM, JVM上で動作する Perl6のサブセットとなっている.</li> | |
368 <li>NQPの基本文法はPerl6に準拠しているが, 束縛ベースで変数を利用するなどいくつか異なる点が存在する.</li> | |
369 <li>NQPは最終的にブートストラップを行う処理系であるが, 初回のビルド時には, すでに書かれたMoarVM, JVMのバイトコードを必要とする. | |
370 <ul> | |
371 <li>この状態をStage0といい, Stage0を利用してStage1, Stage1を利用してStage2をビルドする事で完成する.</li> | |
372 </ul> | |
373 </li> | |
374 <li>NQPの実行可能なインタプリタである<code>nqp</code>は, MoarVMの実行バイナリ<code>moar</code> にライブラリパスなどを設定し, ビルドしたライブラリなどを引数として渡すシェルスクリプトとなっている.</li> | |
375 <li><code>nqp</code> を実行する事でREPLが起動され, NQPスクリプトを <code>nqp</code> に入力として与える事で, 通常のスクリプト言語の様に実行する事が可能となる.</li> | |
376 <li>NQPの設計はRoastで定義されているPerl6とは異なり, 今後も変化していく事が公表されている.</li> | |
377 </ul> | |
378 | |
379 <pre><code>#! nqp | |
380 | |
381 sub fib($n) { | |
382 $n < 2 ?? $n !! fib($n-1) + fib($n - 2); | |
383 } | |
384 | |
385 my $N := 29; | |
386 | |
387 my $z := fib($N); | |
388 | |
389 say("fib($N) = " ~ fib($N)); | |
390 </code></pre> | |
391 | |
392 | |
393 | |
394 </div> | |
395 | |
396 <div class='slide'> | |
397 <!-- _S9SLIDE_ --> | |
398 <h2 id="cbcによるmoarvm">CbCによるMoarVM</h2> | |
399 | |
400 <ul> | |
401 <li>MoarVMの中心部分はバイトコードを解釈するバイトコードインタプリタである.</li> | |
402 <li>その為, CbCを用いてMoarVMのバイトコードインタプリタ部分の書き換えを検討する.</li> | |
403 </ul> | 290 </ul> |
404 | 291 |
405 | 292 |
406 | 293 |
407 </div> | 294 </div> |
456 <li>その為, 入出力としてMoarVMの情報をまとめた構造体interpのポインタであるINTERPを受け渡し, これを利用してアクセスする</li> | 343 <li>その為, 入出力としてMoarVMの情報をまとめた構造体interpのポインタであるINTERPを受け渡し, これを利用してアクセスする</li> |
457 </ul> | 344 </ul> |
458 | 345 |
459 <pre><code>typedef struct interp { | 346 <pre><code>typedef struct interp { |
460 MVMuint16 op; | 347 MVMuint16 op; |
461 /* Points to the place in the bytecode | |
462 right after the current opcode. */ | |
463 /* See the NEXT_OP macro for making sense | |
464 of this */ | |
465 MVMuint8 *cur_op; | 348 MVMuint8 *cur_op; |
466 /* The current frame’s bytecode start. */ | |
467 MVMuint8 *bytecode_start; | 349 MVMuint8 *bytecode_start; |
468 /* Points to the base of the current | |
469 register set for the frame we | |
470 * are presently in. */ | |
471 MVMRegister *reg_base; | 350 MVMRegister *reg_base; |
472 /* Points to the current compilation unit | 351 /* Points to the current compilation unit |
473 . */ | 352 . */ |
474 MVMCompUnit *cu; | 353 MVMCompUnit *cu; |
475 /* The current call site we’re | 354 /* The current call site we’re |
490 <ul> | 369 <ul> |
491 <li>バイトコードに対応する命令をそれぞれCodeGearに変換していく.</li> | 370 <li>バイトコードに対応する命令をそれぞれCodeGearに変換していく.</li> |
492 <li><code>OP(.*)</code>の<code>(.*)</code>の部分をCodeGearの名前として先頭に <code>cbc_</code> をつけた上で設定する.</li> | 371 <li><code>OP(.*)</code>の<code>(.*)</code>の部分をCodeGearの名前として先頭に <code>cbc_</code> をつけた上で設定する.</li> |
493 <li>cur_opなどはINTERPを経由してアクセスする様に修正する.</li> | 372 <li>cur_opなどはINTERPを経由してアクセスする様に修正する.</li> |
494 <li>末尾の <code>NEXT</code> を次のCodeGearにアクセスする為に <code>cbc_next</code> に修正する.</li> | 373 <li>末尾の <code>NEXT</code> を次のCodeGearにアクセスする為に <code>cbc_next</code> に修正する.</li> |
495 <li> | 374 <li>case文で次のcase文に流れる箇所は, 直接その下のcase文に該当するCodeGearに遷移する.</li> |
496 case文で次のcase文に流れる箇所は, 直接その下のcase文に該当するCodeGearに遷移する. | 375 <li>GC対策の為に, CodeGear中のローカル変数をグローバル変数の配列に保存している箇所は,CodeGearに直接処理を書かず, CodeGearから別の関数を呼び出す形に修正する |
497 </li> | 376 <ul> |
498 <li>論文執筆時はstaticに修正する必要があったが, その後CbCコンパイラの改良により不要となった.</li> | 377 <li>その際に, 保存するローカル変数をstatic変数に修正するなどの工夫を行う</li> |
378 </ul> | |
379 </li> | |
499 </ul> | 380 </ul> |
500 | 381 |
501 <pre><code>__code cbc_no_op(INTERP i){ | 382 <pre><code>__code cbc_no_op(INTERP i){ |
502 goto cbc_next(i); | 383 goto cbc_next(i); |
503 } | 384 } |
528 } | 409 } |
529 MVM_repr_unshift_o(i->tc, i->tc->compiling_scs, sc); | 410 MVM_repr_unshift_o(i->tc, i->tc->compiling_scs, sc); |
530 i->cur_op += 2; | 411 i->cur_op += 2; |
531 goto cbc_next(i); | 412 goto cbc_next(i); |
532 } | 413 } |
414 </code></pre> | |
415 | |
416 | |
417 | |
418 </div> | |
419 | |
420 <div class='slide'> | |
421 <!-- _S9SLIDE_ --> | |
422 <h2 id="nqp">NQP</h2> | |
423 <ul> | |
424 <li>Perl6の機能を制約したプログラミング言語であり, Perl6はNQPで記述されている | |
425 <ul> | |
426 <li>その為Perl6処理系は, NQPの動作を目的に実装することでPerl6の動作が可能となる</li> | |
427 <li>NQPコンパイラ自身もNQPで記述されている</li> | |
428 </ul> | |
429 </li> | |
430 <li>Perl6と違い, 変数の宣言を <code>:=</code> を利用した束縛で行う, <code>++</code> 演算子が使用できないなどの違いがある</li> | |
431 <li>nqpのオペコードを利用する際に,型を指定する事が可能である</li> | |
432 </ul> | |
433 | |
434 <pre><code>sub add_test(int $n) { | |
435 my $sum := 0; | |
436 while nqp::isgt_i($n,1) { | |
437 $sum := nqp::add_i($sum,$n); | |
438 $n := nqp::sub_i($n,1); | |
439 } | |
440 return $sum; | |
441 } | |
442 | |
443 say(add_test(10)); | |
533 </code></pre> | 444 </code></pre> |
534 | 445 |
535 | 446 |
536 | 447 |
537 </div> | 448 </div> |
633 1169 goto NEXT; | 544 1169 goto NEXT; |
634 $2 = 162 | 545 $2 = 162 |
635 </code></pre> | 546 </code></pre> |
636 | 547 |
637 | 548 |
549 | |
550 </div> | |
551 | |
552 <div class='slide'> | |
553 <!-- _S9SLIDE_ --> | |
554 <h2 id="アレ">アレ</h2> | |
555 | |
556 <pre><code>100 MVM_STATIC_INLINE MVMint64 MVM_BC_get_I64(const MVMuint8 *cur_op, int offset) { | |
557 101 const MVMuint8 *const where = cur_op + offset; | |
558 102 #ifdef MVM_CAN_UNALIGNED_INT64 | |
559 103 return *(MVMint64 *)where; | |
560 104 #else | |
561 105 MVMint64 temp; | |
562 106 memmove(&temp, where, sizeof(MVMint64)); | |
563 107 return temp; | |
564 108 #endif | |
565 109 } | |
566 </code></pre> | |
567 | |
568 | |
569 | |
638 </div> | 570 </div> |
639 | 571 |
640 <div class='slide'> | 572 <div class='slide'> |
641 <!-- _S9SLIDE_ --> | 573 <!-- _S9SLIDE_ --> |
642 <h2 id="moarvmのデバッグ">MoarVMのデバッグ</h2> | 574 <h2 id="moarvmのデバッグ">MoarVMのデバッグ</h2> |
690 <div class='slide'> | 622 <div class='slide'> |
691 <!-- _S9SLIDE_ --> | 623 <!-- _S9SLIDE_ --> |
692 <h2 id="cbcmoarvmの欠点">CbCMoarVMの欠点</h2> | 624 <h2 id="cbcmoarvmの欠点">CbCMoarVMの欠点</h2> |
693 | 625 |
694 <ul> | 626 <ul> |
695 <li>CbCコンパイラがバグを発生させやすく, 意図しない挙動を示す事がある</li> | 627 <li>CbCコンパイラがバグを発生させやすく, 意図しない挙動を示す事がある |
628 <ul> | |
629 <li>CbCコンパイラ自体のバグも存在する</li> | |
630 </ul> | |
631 </li> | |
696 <li>MoarVMのオリジナルの更新頻度が高い為, 追従していく必要がある</li> | 632 <li>MoarVMのオリジナルの更新頻度が高い為, 追従していく必要がある</li> |
697 <li>CodeGear側からCに戻る際に手順が複雑となる</li> | 633 <li>CodeGear側からCに戻る際に手順が複雑となる</li> |
698 <li>CodeGearを単位として用いる事で複雑なプログラミングが要求される.</li> | 634 <li>CodeGearを単位として用いる事で複雑なプログラミングが要求される.</li> |
699 </ul> | 635 </ul> |
700 | 636 |
702 | 638 |
703 </div> | 639 </div> |
704 | 640 |
705 <div class='slide'> | 641 <div class='slide'> |
706 <!-- _S9SLIDE_ --> | 642 <!-- _S9SLIDE_ --> |
643 <h2 id="threadedcodeの実装">ThreadedCodeの実装</h2> | |
644 | |
645 <ul> | |
646 <li>MoarVM内のオペコードに対応する処理が分離出来たことにより, オペコードに該当するCodeGearを書き連ねることによってThreadedCodeが実装可能となる</li> | |
647 </ul> | |
648 | |
649 | |
650 | |
651 </div> | |
652 | |
653 <div class='slide'> | |
654 <!-- _S9SLIDE_ --> | |
707 <h2 id="cbcmoarvmと通常のmoarvmの比較">CbCMoarVMと通常のMoarVMの比較</h2> | 655 <h2 id="cbcmoarvmと通常のmoarvmの比較">CbCMoarVMと通常のMoarVMの比較</h2> |
708 | 656 |
709 <ul> | 657 <ul> |
710 <li>CbCMoarVMと通常のMoarVMの速度比較を行った</li> | 658 <li>CbCMoarVMと通常のMoarVMの速度比較を行った</li> |
659 <li>対象として, 単純なループで数値をインクリメントする例題と, フィボナッチ数列を求める例題を選択した</li> | |
660 <li>NQPで実装した場合とPerl6で実装した場合の速度を計測した</li> | |
711 </ul> | 661 </ul> |
712 | 662 |
713 <pre><code>#! nqp | 663 <pre><code>#! nqp |
714 # Example of a while loop | 664 |
665 my $count := 100_000_000; | |
715 | 666 |
716 my $i := 0; | 667 my $i := 0; |
717 while $i < 10 { | 668 |
718 say("i={$i++}"); | 669 while ++$i <= $count { |
719 } | 670 } |
720 </code></pre> | 671 </code></pre> |
721 | 672 |
722 <pre><code>subset Fizz of Int where * %% 3; | 673 <pre><code>#! nqp |
723 subset Buzz of Int where * %% 5; | 674 |
724 subset FizzBuzz of Int where Fizz&Buzz; | 675 sub fib($n) { |
725 subset Number of Int where none Fizz|Buzz; | 676 $n < 2 ?? $n !! fib($n-1) + fib($n - 2); |
726 | 677 } |
727 proto sub fizzbuzz ($) { * } | 678 |
728 multi sub fizzbuzz (FizzBuzz) { "FuzzBuzz" } | 679 my $N := 29; |
729 multi sub fizzbuzz (Fizz) { "Fizz" } | 680 |
730 multi sub fizzbuzz (Buzz) { "Buzz" } | 681 my $t0 := nqp::time_n(); |
731 multi sub fizzbuzz (Number $number) { $number } | 682 my $z := fib($N); |
732 | 683 my $t1 := nqp::time_n(); |
733 fizzbuzz($_).say for 1..15; | 684 |
734 | 685 say("fib($N) = " ~ fib($N)); |
735 </code></pre> | 686 say("time = " ~ ($t1-$t0)); |
687 | |
688 </code></pre> | |
689 | |
690 | |
691 </div> | |
692 | |
693 <div class='slide'> | |
694 <!-- _S9SLIDE_ --> | |
695 <h1 id="フィボナッチの例題">フィボナッチの例題</h1> | |
696 | |
697 <ul> | |
698 <li>フィボナッチの例題ではCbCMoarVMが劣る結果となった</li> | |
699 </ul> | |
700 | |
701 | |
702 | |
703 </div> | |
704 | |
705 <div class='slide'> | |
706 <!-- _S9SLIDE_ --> | |
707 <h2 id="単純ループ">単純ループ</h2> | |
708 | |
709 <ul> | |
710 <li>オリジナル | |
711 <ul> | |
712 <li>7.499 sec</li> | |
713 <li>7.844 sec</li> | |
714 <li>6.074 sec</li> | |
715 </ul> | |
716 </li> | |
717 <li>CbCMoarVM | |
718 <ul> | |
719 <li>6.135 sec</li> | |
720 <li>6.362 sec</li> | |
721 <li>6.074 sec</li> | |
722 </ul> | |
723 </li> | |
724 <li>単純ループではCbCMoarVMの方が高速に動作する場合もある</li> | |
725 </ul> | |
726 | |
727 | |
728 | |
729 </div> | |
730 | |
731 <div class='slide'> | |
732 <!-- _S9SLIDE_ --> | |
733 <h2 id="まとめ">まとめ</h2> | |
734 | |
735 <ul> | |
736 <li>速度を計測した所, 現在はCbCMoarVMの方が僅かに劣る結果となった</li> | |
737 <li>ただしフィボナッチを求める例題などで, ケースによってはCbCMoarVMの方が高速に動作する場合もある</li> | |
738 </ul> | |
739 | |
740 | |
741 | |
742 </div> | |
743 | |
744 <div class='slide'> | |
745 <!-- _S9SLIDE_ --> | |
746 <h2 id="まとめと今後の課題">まとめと今後の課題</h2> | |
747 <ul> | |
748 <li>継続と基本としたC言語 Continuation Based Cを用いてPerl6の処理系の一部を書き直した</li> | |
749 <li>CbCの持つCodeGearによって, 本来はモジュール化出来ない箇所をモジュール化する事が出来た</li> | |
750 <li>MoarVMの速度改善にはThreadedCodeが期待でき, CodeGearベースの命令ディスパッチとThreadedCodeは相性が良いと考えられる</li> | |
751 <li>今後は実行するバイトコードによりThreadedCode箇所と通常の配列を読み取り, 次のCodeGearを計算する処理を両立させていく</li> | |
752 </ul> | |
753 | |
736 | 754 |
737 </div> | 755 </div> |
738 | 756 |
739 | 757 |
740 </div><!-- presentation --> | 758 </div><!-- presentation --> |