Mercurial > hg > Papers > 2020 > koo-thesis
annotate Slide/Slide.md @ 22:b96b3244307b
update paper & slide
author | e165727 <e165727@ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 16 Feb 2020 18:20:36 +0900 |
parents | 05eac76e8c24 |
children | 58dd8e127e4b |
rev | line source |
---|---|
7 | 1 title: Perl6(Raku)のサーバーを使った高速実行 |
2 author: Kouki Fukuda, Shinji Kono | |
3 profile: 琉球大学 | |
4 | |
22 | 5 ## スクリプト言語の高速実行 |
16 | 6 - 現在多くのスクリプト言語はインタプリタ型言語であり, 実行時にインタプリタの立ち上げ, モジュールを読み込み, スクリプトの解釈, スクリプトの実行 といったような処理を担っている. |
7 - これらの処理の中にはOS上で事前に行うことで, より起動時間, 及び処理時間の短縮が予想される. | |
22 | 8 - 頻繁にコードを書き換え実行するスクリプト言語では起動時間をできるだけ短くしたい. |
9 - その手法として同一ホスト内で終了せずに実行を続けるサーバープロセスを立ち上げ, このサーバープロセス上で立ち上げておいたコンパイラに実行するファイル名を転送し, サーバー上でコンパイルを行う手法を提案する | |
10 - この提案手法に沿って『Abyss サーバー』を実装した. | |
11 - またスクリプト言語の速度改善を行うにあたり, 本研究では Raku というスクリプト言語を用いた. | |
7 | 12 |
16 | 13 <!-- |
7 | 14 ## 研究概要 |
15 - Raku の実装の一つであるRakudoは、Byte code である MoarVM と、それ上で動作する Raku のsubsetであるnqp (Not Quite Perl)上に構成されている。 | |
16 - 現状のRakuの実行はRakuで記述されたコンパイラをloadしてJITしながら実行すること自体に時間がかかっている。 | |
17 - そこで, 同一ホスト内で終了せずに実行を続けるサーバープロセスを立ち上げ, このサーバープロセス上で立ち上げておいたコンパイラに実行するファイル名を転送し, サーバー上でコンパイルを行う手法を提案し実装する. | |
16 | 18 --> |
7 | 19 |
20 ## Raku と他言語の起動時間の比較 | |
16 | 21 - Raku と他言語の起動時間の比較行なった. |
7 | 22 - 実行環境 |
23 | |
24 ``` | |
25 macOS Mojave version 10.14.5 | |
26 メモリ8GB | |
27 プロセッサ2.7GHz Intel Core i5 | |
28 ``` | |
29 | |
15
e2d2da777af0
update Slide & add NativeCall section
e165727 <e165727@ie.u-ryukyu.ac.jp>
parents:
7
diff
changeset
|
30 - perl5,ruby,raku,pythonでhelloworldを出力するプログラムを用いて行なった実行結果である. |
7 | 31 <table style="border-collapse: collapse;" border="1" width="400" height="300"> |
32 <tr> | |
33 <th>Language</th> | |
34 <th>Version</th> | |
15
e2d2da777af0
update Slide & add NativeCall section
e165727 <e165727@ie.u-ryukyu.ac.jp>
parents:
7
diff
changeset
|
35 <th>Time</th> |
22 | 36 <th>Ratio</th> |
7 | 37 </tr> |
38 <tr> | |
39 <td>raku</td> | |
40 <td>2019.03.1</td> | |
15
e2d2da777af0
update Slide & add NativeCall section
e165727 <e165727@ie.u-ryukyu.ac.jp>
parents:
7
diff
changeset
|
41 <td>249 ms</td> |
22 | 42 <td>62.25</td> |
7 | 43 </tr> |
44 <tr> | |
45 <td>perl5</td> | |
46 <td>v5.18.4</td> | |
15
e2d2da777af0
update Slide & add NativeCall section
e165727 <e165727@ie.u-ryukyu.ac.jp>
parents:
7
diff
changeset
|
47 <td>4 ms</td> |
22 | 48 <td>1</td> |
7 | 49 </tr> |
50 <tr> | |
51 <td>python</td> | |
52 <td>2.7.10</td> | |
15
e2d2da777af0
update Slide & add NativeCall section
e165727 <e165727@ie.u-ryukyu.ac.jp>
parents:
7
diff
changeset
|
53 <td>13 ms</td> |
22 | 54 <td>3.25</td> |
7 | 55 </tr> |
56 <tr> | |
57 <td>ruby</td> | |
58 <td>2.3.7p456</td> | |
15
e2d2da777af0
update Slide & add NativeCall section
e165727 <e165727@ie.u-ryukyu.ac.jp>
parents:
7
diff
changeset
|
59 <td>83 ms</td> |
22 | 60 <td>20.75</td> |
7 | 61 </tr> |
62 </table> | |
63 | |
22 | 64 Perl5 を基準とすると Raku はその62.25倍と非常に起動時間が遅いことがわかる. |
65 | |
66 <!-- | |
7 | 67 ## Rakudo |
68 - Rakudoとは現在のRakuの主力な実装である.(Raku は言語名, Rakudo はコンパイラ) | |
69 - Rakudo は MoarVM, と NQP と呼ばれる Raku のサブセット, NQP と Raku 自身で記述された Raku という構成である. | |
70 - Rakudo は MoarVMの他に JVM やJava Script を動作環境として選択可能である. | |
71 | |
72 ![](fig/Rakudo.svg) | |
73 - Rakudoの構成 | |
22 | 74 --> |
7 | 75 |
22 | 76 <!-- |
7 | 77 ## NQP |
78 - NQPとはNot Quite Perl の略で Raku のサブセットである. | |
79 - 基本的な文法などは Raku に準拠しているが, 変数を束縛で宣言するなどの違いがある. | |
80 - NQPコンパイラ自身もNQPで記述されている | |
81 - NQP は MoarVM や JVMの違いを吸収してAPIを提供している | |
22 | 82 --> |
7 | 83 |
84 ## MoarVM | |
85 - MoarVM は Raku に特化したVM | |
86 - C 言語で実装されている | |
87 - JIT コンパイルなどが現在導入されているが, 起動時間などが低速である問題がある | |
88 | |
22 | 89 <!-- |
7 | 90 ## Perl6 の名称変更 |
91 - Raku はPerlの次期メジャーバージョンとして設計が始められ, 元々Perl6という名称であったが, Perl6 は言語仕様及び処理実装が Perl5 と大幅に異なっており, 言語的な互換性が存在しないため別名がつけられました. | |
92 - 現在有力な処理系である Rakudo から名前を取り Raku という別名がつけられた. | |
93 | |
94 ## Rakudoの語源 | |
95 - ちなみに Rakudo の語源は, 楽土と駱駝道で | |
22 | 96 - 楽土の方は日本語で「楽園」という意味で |
7 | 97 - 駱駝道の方は Perlのマスコットキャラクターが🐪だったからです |
98 - http://blogs.perl.org/users/zoffix_znet/2017/07/the-hot-new-language-named-rakudo.html | |
22 | 99 --> |
7 | 100 |
101 ## Rakuが遅い理由 | |
102 - 通常 Ruby のようなスクリプト言語ではまず YARV などのプロセスVM が起動し,その後スクリプトを Byte code に変換して実行という手順を踏む. | |
22 | 103 - |
7 | 104 - Rakudo はインタプリタの起動時間及び, 全体的な処理時間が他のスクリプト言語と比較して低速である. |
105 - これは Rakudo 自体が Raku と NQP で書かれているため, MoarVMを起動し, Rakudo と NQP のByte codeを読み取り, Rakudoを起動し, その後スクリプトを読み取り, スクリプトの Byte code 変換というような手順で進むためである. | |
106 - また Raku は実行時の情報が必要であり, メソッドを実行する際に invoke が走ることも遅い原因である. | |
107 - invoke はMoarVM の method 呼び出しのbyte codeです. | |
108 | |
109 ## Raku による Abyss Server の実装 | |
110 - 提案手法に沿い『Abyss Server』を実装した. | |
111 - Abyss Server はUnix domain socketを用いて送信した Raku スクリプトを実行するための Server である. | |
112 - 下記の図は, Abyss Server を用いたスクリプト言語の実行手順です. | |
113 | |
114 ![](fig/Abyss.svg) | |
115 | |
22 | 116 <!-- |
7 | 117 ## Raku の Unix domain socket 実装 |
118 - Unix domain socket でなくINET で実装した場合, 他者からスクリプトを送りつけられる可能性がある. | |
119 - そのため今回はUnix domain socket を用いて実装しました. | |
120 - Rakuには現在Unix domain socketの実装がないため, Unix domain socket の実装を行なった. | |
121 - IO::Socketがroleとして定義されている | |
122 - Raku での role は他の言語の interface に相当するものである | |
123 - 現状 Raku にはIO::Socket::INETとIO::Socket::Asyncの実装がある | |
124 - 先ほど上で説明したようにINETとAsyncはセキュリティの問題で使えない | |
125 - IO::Socketを実装した IO::Socket::Unix を実装した | |
126 - IO::Socket::Unixの中ではnqpの機能を使う必要がある | |
22 | 127 --> |
128 | |
7 | 129 |
130 ## 通常実行と提案手法の速度比較 | |
131 - 今回は,提案手法での実行速度と通常実行での実行速度, この二つの速度の比較を行う | |
132 - 題材として行うのはhelloworldを出力するだけのプログラムとフィボナッチ数列の例題である. | |
133 | |
134 ## 予測 | |
135 - 前述した通り, Raku はコンパイラの起動に時間がかかっているため, 提案手法を用いることで起動時間分早く実行することができると予測する. | |
136 | |
137 ## 実行結果 | |
138 | |
139 - 通常実行 | |
140 - 0.2695 sec | |
141 - 0.2131 sec | |
142 - 0.3143 sec | |
143 | |
144 - 提案手法 | |
145 - 0.0238 sec | |
146 - 0.0219 sec | |
147 - 0.0275 sec | |
148 | |
149 - 提案手法は通常実行に比べて約10倍早い実行結果になった | |
150 | |
151 ## フィボナッチ数列の例題 | |
152 | |
153 - 通常実行 | |
154 - 0.2128 sec | |
155 | |
156 - 提案手法 | |
157 - 0.0415 sec | |
158 | |
159 - 先ほどと同様,提案手法は通常実行に比べて早い結果となり,約5倍早い実行結果になった | |
160 | |
161 ## Abyss Server側の実装 | |
162 - Abyss Server は起動すると, まず自身にファイルパスを転送するためのソケットを生成し, その後ファイルを受け取るための待機ループに入る. | |
163 - ファイルパスを受け取ると, ファイルを開き実行する. | |
164 | |
165 ``` | |
16 | 166 sub close(int32) returns int32 is native { ... } |
167 sub dup(int32 $old) returns int32 is native { ... } | |
168 sub dup2(int32 $new, int32 $old) returns int32 is native { ... } | |
169 | |
170 method readeval | |
171 { | |
172 my $listen = IO::Socket::Unix.new( :listen, | |
173 :localhost<localhost>, | |
174 :localport(3333) ); | |
175 my $backup = dup(1); | |
176 say DateTime.now; | |
177 | |
178 loop | |
179 { | |
180 my $conn = $listen.accept; | |
181 my $sock_msg; | |
182 my $buf = $conn.recv(); | |
183 $sock_msg = $buf; | |
184 close(1); | |
185 dup2($conn.native-descriptor(), 1); | |
186 EVALFILE $sock_msg; | |
187 dup2($backup, 1); | |
188 close($backup); | |
189 $conn.close; | |
7 | 190 } |
16 | 191 |
192 $listen.close; | |
193 }} | |
7 | 194 ``` |
195 | |
196 ## Abyss Client側の実装 | |
197 - ユーザーは Abyss Server を起動後,ファイルパスをサーバーに送信する. | |
198 | |
199 ``` | |
200 use IO::Socket::Unix; | |
16 | 201 |
202 my $conn = IO::Socket::INET.new( :host<localhost>, | |
7 | 203 :port(3333) ); |
204 | |
16 | 205 $conn.print: 'Absolute file path'; |
206 | |
22 | 207 my $sock_msg; |
16 | 208 |
22 | 209 while my $buf = $conn.recv(:bin) |
210 { | |
211 $sock_msg = $buf.decode; | |
212 last; | |
213 } | |
214 | |
215 say $sock_msg; | |
7 | 216 ``` |
217 | |
22 | 218 <!-- |
7 | 219 ## Raku のEVAL |
220 - Raku では EVAL 関数があり文字列を Raku のソースコード自身として評価できる | |
221 - Raku では, EVAL は通常は使用できないようになっており, MONKEY-SEE-NO-EVAL という pragma を実行することで使うことができるようになる. | |
222 | |
223 ``` | |
224 use MONKEY-SEE-NO-EVAL; | |
225 | |
226 EVAL "say { 5 + 5 }"; # OUTPUT: 10 | |
227 ``` | |
228 | |
229 - EVALFILEはファイルパスを受け取ると, ファイルの中身をバイト文字列に変換し, それをEVALと同様に解釈する. | |
22 | 230 --> |
7 | 231 |
232 ## Abyss Serverの利点 | |
233 - Abyss Serverを用いて実行することで, サーバー上で事前に起動した Rakudo を再利用し, 投げられた Raku スクリプトの実行を行うため, Rakudo の起動時間を短縮できる. | |
234 - 約10倍早くなる | |
235 - 一度投げられたスクリプトのバイトコード, もしくは計算結果をキャッシュで保存しておき, 再度実行する際に, そのキャッシュを用いてコンパイル時間を省くような仕組みを入れやすいと考えられる. | |
236 - 他の起動時間遅いスクリプト言語や, モジュールの読み込みが遅い言語などにも, 応用しやすいと考えられる. | |
237 - 普通のスクリプト言語だと実行するたびにforkして実行しインタプリタの立ち上げという処理になるが, プロセス毎回起動しなくて済む | |
238 | |
239 ## Abyss Serverの欠点 | |
240 - 現在 Abyss Server には 一度スクリプトを実行した後にサーバー内の環境をリセットする機能が存在しないため,スクリプトがサーバー内の環境に影響を及ぼした場合,通常実行と違う挙動をする危険性がある | |
241 - 同時に二つ以上のタスクを与えられると実行順のスケジューリングができない | |
242 - 与えられた順番に処理していく | |
243 - 異常に長いタスクが投げられた場合, 次のタスクが前のタスクが終わるまで実行ができない | |
244 - 起動時のオプションが選択出来ない | |
245 | |
22 | 246 ## OS上でスクリプト言語を実行する方法の改善点 |
247 - | |
248 | |
7 | 249 ## まとめと今後の課題 |
250 - Raku の新たな実行方法の提案,及び実装を行なった. | |
251 - Raku にUnix domain socket の実装を行なった. | |
252 - Raku の速度改善において, 同一ホスト内でサーバープロセスを生成し,サーバープロセス内であらかじめコンパイラを立ち上げて起き, 実行するファイル名を転送し,サーバープロセス上でコンパイルを行う手法は有効であると考えられる | |
253 - 今後は一度投げられたスクリプトをキャッシュで保存しておき,再度実行する際に,そのキャッシュを用いてコンパイル時間を省くような仕組みを入れて開発を進めたいです. |