* HLX-001
-(by [[K]], 2021.06.20)

** (0)
-HLXは、[[a21_txt01]]やその続編で作ったHLシリーズ(はりぼて言語)をベースに、[[K]]が望む理想の言語を作るプロジェクトです。
--中・長期の目標は[[a21_hlx000]]に書いてあります。
-HLX-001はその最初のバージョンです。まあHL-23みたいなものです。

** (1) 概要
-HLX-001は、HL-9a, HL-16a, HL-22aの3つを統合し、さらに改良を加えたものです。
--ということで「できること」はこれら3つと同じです。
-統合されているので、モードを切り替えて使います。
--[codemode 0] HL-9a相当の実行モードで、JITコンパイルせずに中間コードを実行します。x86, x64以外でも(ソースからHLX-001をコンパイルすれば)動くはずです。
--[codemode 1] HL-16a相当の実行モードで、x86の32bitの機械語をJITコンパイラで生成します。
//---64bit版でもこのモードを利用することができますが、64bit版は32bit用の機械語を実行できないので、 codedump 1 で機械語を表示することしかできません(将来のバージョンではアセンブラも出力できます)。
--[codemode 2] HL-22a相当の実行モードで、x64の64bitの機械語をJITコンパイラで生成します(MS-Windows系のABI)。
//---32bit版でもこのモードを利用することができますが、32bit版は64bit用の機械語を実行できないので、 codedump 1 で機械語を表示することしかできません(将来のバージョンではアセンブラも出力できます)。
--[codemode 3] HL-22a相当の実行モードで、x64の64bitの機械語をJITコンパイラで生成します(System V系のABI)。
//---以下同文。・・・しかし、codemode 3は全くデバッグしてないので、このバージョンではきちんと動かないかもしれません。

-[Q]そもそもなぜ3つを統合する必要があるの?
--[A]HLシリーズを拡張していくにあたって、それぞれの改造を3つのバージョンに別々に適用していくのは大変なので、まず1つに統合して、それから拡張していきたかったのです。
--さらに統合することで、3つを別々に持つよりもコンパクトにできるのではないかと考えています。
--あと、これ一つであれもこれもできる!っていうのが好きなんです(笑)。

-http://k.osask.jp/files/hlx001a.zip (75.3KB)
--[内容]
--hlx001_32.exe : 32bit版の実行ファイル(21.5KB)
--hlx001_64.exe : 64bit版の実行ファイル(29.0KB)
--mandel.cなどのサンプルプログラム
--hlx001src/
---hlx001.c (935行) - ソースコードから共通中間コードに変換
---esvm.c (945行) - 共通中間コードを最適化する
---esvm_run.c (200行) - 共通中間コードをインタプリタで実行
---esvm_x864.c (1027行) - 共通中間コードをx86/x64の機械語に変換

** (2) 特徴(なにがすごいのか)
-[1]処理系の小ささ
--HL-9a, HL-16a, HL-22aの3つは以下のようになっていました。それらに対し、こんなにコンパクトにまとまっています。
||ソース行数|.exeのサイズ(無圧縮)|.exeのサイズ(UPX)|
|HL-9a|RIGHT:772行|RIGHT:20.0KB|RIGHT:11.5KB|
|HL-16a|RIGHT:1081行|RIGHT:24.5KB|RIGHT:13.5KB|
|HL-22a|RIGHT:1223行|RIGHT:41.5KB|RIGHT:21.0KB|
|(合計)|RIGHT:(3076行)|RIGHT:(86.0KB)|RIGHT:(46.0KB)|
|||||
|HLX-001|RIGHT:3017行|RIGHT:40.0KB|RIGHT:21.5KB|
--あれ?ソース行数的には、それほどコンパクトでもないな・・・。
--まあでも実行ファイル的には明らかにコンパクトになっています。
--上記3つは似たような部分が多いため、1つにまとめることで共通な部分が省かれて、このような結果になっています。

~

-[2]コード生成の質の向上
--mandel.cを使って比較してみました。

--[2-1] HL-9aとの比較
|HL-9a vs HLX-001|32bitモード(x86)|29.667秒 vs ''23.220秒''|1.28倍速|
|HL-9a vs HLX-001|64bitモード(x64)|26.904秒 vs ''18.653秒''|1.44倍速|
---表のように、HLX-001は中間コードの実行性能が上がっています。
---この成果は、主に「中間コードの最適化」(後述)がうまくいっているからです。
--[2-2] HL-16aとの比較(32bitモード(x86))
|HL-16a vs HLX-001|3.246秒(657バイト) vs ''3.272秒(609バイト)''|速度優先|
|HL-16a vs HLX-001|3.730秒(613バイト) vs ''3.660秒(411バイト)''|サイズ優先|
---速度優先: regVar(0, zx, zy, xx, yy, t, cx, cy, n);
---サイズ優先: regVar(0, n, zx, zy, x, y, sx, sy, sn);
---実行速度的にはHL-16aに対する優位性はないのですが、生成コードの長さは結構改善されています。

--[2-3] HL-22aとの比較(64bitモード(x64))
|HL-22a vs HLX-001|2.503秒(674バイト) vs ''2.512秒(655バイト)''|速度優先|
|HL-22a vs HLX-001|3.449秒(588バイト) vs ''3.459秒(489バイト)''|サイズ優先|
---速度優先: regVar(0, zx, zy, xx, yy, t, cx, cy, n);
---サイズ優先: regVar(0, n, zx, zy, x, y, sx, sy, sn);
---実行速度的にはHL-22aに対する優位性はないのですが、生成コードの長さは結構改善されています。

** (3) プログラムの構成
-hlx001.c (935行)
--これはHL-9aから内部コード実行ルーチンを引いたようなものです。
--内部コード(共通中間コード)を出力した後は、esvm.cやesvm_run.cやesvm_x864.cを使ってプログラムを実行します。
-esvm.c (945行)
--共通中間コードを最適化します。
-esvm_run.c (200行)
--共通中間コードをJITコンパイルせずに実行します。
-esvm_x864.c (1027行)
--共通中間コードからx86/x64の機械語をJITコンパイラで生成します。

~

-この構成は、esvm.c, esvm_run.c, esvm_x864.cを再利用することを想定したものです。
-将来また別の言語を作りたくなった時には、hlx001.cに相当する部分だけを作り替えるだけで、今回くらいの最適化が適用できるはずです。
--935行のプログラムを書くだけで、いろんな方法で実行できる言語が21.5KBでできてしまうっていうのは、私にとっては相当に便利なことなのです。

** (4) 先送りされた課題
-どれも「ちゃんとするまで仕上げるよりも、ひとまず動くようになった段階でHLX-001としてリリースしてしまおう」と考えたことによるものです。

-hlx001.c側で、実行ターゲットに応じたセットアップをしている部分が残っていて、それがよくない(もっときれいに分けられるべき)。
-hlx001.cではソースコードの長さが長すぎるとバッファオーバーランしてしまう。これを可変長にするべき。
-HL-16bやHL-22bは「codedump 2」でアセンブラのソースが出力できたが、HLX-001にはその機能がない。
-浮動小数点演算や構造体のサポートが全くできてない。配列のサポートも貧弱。

** (5) どんな最適化をしているか?



-(以下編集中)


----

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS