JITの高速化の続き
現在./configure の--with-jitは有効じゃありません。
とりあえず、今回の収穫はLLVMでのグローバル変数のアクセスの仕方がわかったことと、構造体のフィールドのアクセスの仕方がわかったことです。
高速化は順調です。だいぶ速くなると思います。6月末まではちょっとむずかしいかもしれません。7月末までには完成させたいと思います。とりあえず、VMのスタックにアクセスしていないため生成コードが劇的に少なくなっています。かなり高速化は期待できそうです。もし可能であればコンパイル時にJITのコンパイルもしてしまうかもしれません。そうすれば、さらに速くなるでしょう。あんまりするつもりはありませんが、、、。
まあ、完成が楽しみです。
JITのルーチンの書き直し中
現在JITは有効ではありません。--with-jitは./configureに付けないでください。
LLVM用のスタックを用意してLLVMの最適化がかかるように改造中です。今のところ、メソッドコールと一部の演算子、throwなどは動いてます。
一度書いたルーチンを流用してでの書き直しなので、そんなに時間はかからないと思います。のんびりと動かしていっています。
問題は速くなるかですが、なんとかして速度を出したいと思います。
最近Swiftの言語仕様をwikipediaで読みました。高機能で僕が自分の言語でしたいことは大抵してある感じです。インタラクティブにも動きますし。僕の言語の利点はmixin-layersですかね。後は正規表現がファーストクラスオブジェクトな点もちょっと違います。
速度的にはネイティコードを作るSwiftには絶対敵うわけもなく、僕の言語は多分RubyやPythonより遅いと思います。GCかなぁ。mark&sweepでしかもコンパクションまでしているので、遅いと思います。原始的なGCのルーチンなので。また気が向いたらGCのルーチンも改良したいと思います。
速度さえJITで速くなれば、それなりに良い言語だと思います。JITが完成して速度が出るようになればSwiftを参考に幾つか改良点を施したいと思います。nullを代入するために型名の後に?を入れなければならないようにしたり、クラス外の関数を作れるようにしたり。そんなに難しくない変更なので、是非したいと思います。
LLVMのルーチンを書き直してます
高速化のためにLLVMのJITのルーチンを書き直しています。
完全にフルスクラッチからではありませんが、スタックの値をVMのスタックではなくLLVMのスタックを用意して、そこの値を使っています。1+1など単純な計算は最適化されて2とされるでしょう。
今のままだと一度VMのスタックに1を書き込んで、もう一度1を2つ読み込んで足し算して2となっていましたから最適化の余地もありませんでした。
LLVMのスタックからVMのスタックへの値を反映させる関数などは完成しているので、後は大体道なりで書き直せそうです。
今月末か来月末には新しく高速化されたLLVMのルーチンが出来上がるでしょう。
大体僕は2回位書かないとまともなルーチンを書けない癖がありまして。1回目は手探りで、2回目で整理されるって感じですかね。みなさんもそうなのかもしれませんが。
6月末までには大体めどを付けておきます。お楽しみに。
まだだ、まだ終わらんよ。
やっぱり、放っておけなくて速度アップのための処理を書いています。
これで速くならなかったら、本当に諦めます。
処理の結果を毎回VMのスタックに書き込むのをやめて、LLVM用のスタックを用意して、そこに書き込むようにしています。
VMのスタックの値が必要になったら、LLVM用のスタックからVM用のスタックに値を更新するという方法を取ります。
それで速くなるはずです。たぶん。
この処理を書き終えたら、本当にのらプログラマーを引退します。
速くならなくても諦めます。
8月末で現職を退職するので、8月は有休があります。
その時1ヶ月暇になるので、処理を書き終えたいと思います。
凄く速くなったらいいなぁ、、、、。
とりあえず、今日書いた分では、この方法で1+3 == 4は動いています。
まだだ、まだ終わらんよ。
version 1.5リリース
JITが完成しています。メソッド名にjit指定はいりません。内部的に何回か呼ばれたメソッドはJITされます。
ただし、速度の向上は微妙に速くなった程度です。あまり期待しないでください。
さて、やけ酒飲んで。明日からまた仕事に備えるか。
まあ、僕の冒険もここまでですかね。後は拡張ライブラリを作れるようにします。ソケットクラスでも誰か書いてください。
僕は後は知りません。
フィナーレのBGMはThe Beatles「White Album」でした。
JITいらないです。
--with-optimizeの方が重要です。--with-debugだと17秒かかる処理が--with-optimizeで3秒程度になります。この処理の場合、とりあえず、JITしても速度は変わりません。ループ以外のところだと逆に実行時のコンパイルに時間がかかり遅くなります。
ループで非常に重い処理をする場合だけ必要になるかもしれません。なんだったんだ。僕の3ヶ月は。
Javaのようにメソッド単位で何度も呼ばれるメソッドだけJITするようにするのが良いかもしれませんね。それだと意味あるかもしれませんね、、、。
早速そうしてみます。
とりあえず、今日はコンパイル時にLLVMのIRを出力する改造をしてみたりしましたが、結局ロード時の処理がよくわからないエラーで頓挫してます。出力されたIRソースファイルが1万行とか超えていたので、逆に遅くなりそうでしたし。
とりあえず、今から数回呼ばれたメソッドのみコンパイルするように、処理を施してみます。前述の処理が速くなればいいんですが、多分変わらないでしょうね。JITされても大して速くなってないんですよね、、、ほんと微妙に速くなったかな程度で、、、、うーん、がくり。
まあ、僕の冒険もこれで終わりです。後は拡張ライブラリを作れるようにしてソケットクラスを作ったら終わりです。
後はフォークするなり、何してもいいです。GPL縛りがあるので、それは守ってくだされば、どうされても結構です。オープンソースなのでLLVMの処理の参考になったりするでしょうし。
ああ、そろそろ、バージョン上げないといけないですね。1.5として今日リリースします。今日は残念記念としてやけ酒飲みます。がくり。
ただ、もう少しJITの仕方を工夫してみます。まだだ、まだ終わらんよ。
JITのデバッグが終了しました。
デバッグに2週間、作成に2ヶ月半くらいなので、3ヶ月でLLVMでのJITが成功しました。思ったよりは時間がかからなかったですね。
LLVMに関してはまだまだ発展中なので、なかなか使いこなすのが難しかったですが、なんとか、リリースにたどり着けました。
パソコンのしすぎで、奥さんに怒られたりしましたが、なんとかバグもなくなり、ほっとしてます。
しかし、残念なことにJITすると逆に速度がおちます。正直に言っておきますが。最適化のフェーズのうち、一つだけ有効にするとバグが発生するため、外してあるのです。そのせいかなと思います。多分それが重要な最適化で、速度に関係があるのではないかと思っています。
それを有効にしたり、もしくはJITではなく、コンパイルタイムにコンパイルしてしまう方法を考えたりしています。やっぱり実行時にコンパイルするのが遅いと思われるので。
まあ、僕ももうそろそろノラプログラマーとして趣味でコーディングするのも終わらせようと考えているので、速度の問題を解決できたら、ノラプログラマーを引退すると思います。
僕は仕事は介護士をしていて、趣味でプログラミングしています。40歳にも近くなり、結婚もして、だいぶ余暇にプログラミングするのは無理が来ています。仕事してのプログラミングをしたい気もあるのですが、どうしようか、迷っています。介護士としても10年近く仕事をしているので、今更プログラマーになっても使い物になるか分かりませんし。とりあえず、趣味としてのプログラミングはやりきった感じがあります。後はちょくちょくClover2の速度の問題や拡張ライブラリを作成を可能にしたりSocketクラスを作ったりすると思います。やりきった感があるので、もう弱火でちょくちょく改良する程度ですね。しかし、JITを有効にすると遅くなるとは。コンパイルが遅いのかなぁ、、、、モジュールをメソッドごとに何回も登録しているのが遅いんだろうか。はぁ、、、まあ、また解決できればいいなと思います。
ではでは。フィナーレのBGMは無音でした。今日もビール2杯飲んで打ち上げします。JITを有効にしたmake testが全部動いたときはほんと嬉しかったです。それでは。