Back to Peppermint.jp
2010-09-08
HSPをJIT実行
ようやくraytraceが1.7倍速くらいで動くようになった。
http://peppermint.jp/products/hsp/
http://github.com/zakki/openhsp/tree/jit
まんまhsp3cnvと同じだとインタプリタ実行と等速か若干遅いくらいなので、次のあたりを実装した。
パフォーマンス的に効きそうな項目も結構残ってる。
完全に変数の型を解析してかつグローバルに最適化かけられれば10倍速くらいで動いてもいいはずなんだよなー
- hsp3cnv由来で関数の引数が値渡しで済むはずの箇所も参照渡ししている
- (関数で無い)コマンドはそのまま
- 自動型変換が必要な箇所は以前hspvarにまかせている
- ベーシックブロック単位でしか処理していない
あと、機能的にユーザー定義関数やモジュールが使えないのが痛い。
HSPの1行が
d = 1.0 / os.hit
%ptr = load i8** getelementptr inbounds (%struct.PVal* @Var__HspVar43, i32 0, i32 4) ; <i8*> [#uses=1] %0 = bitcast i8* %ptr to i32* ; <i32*> [#uses=1] %1 = load i32* %0 ; <i32> [#uses=1] %ptr1 = load i8** getelementptr inbounds (%struct.PVal* @Var__HspVar13, i32 0, i32 4) ; <i8*> [#uses=1] %2 = bitcast i8* %ptr1 to double* ; <double*> [#uses=1] call void @HspVarCoreReset(%struct.PVal* @Var__HspVar13) call void @HspVarCoreArray2(%struct.PVal* @Var__HspVar13, i32 %1) %offset = load i32* getelementptr inbounds (%struct.PVal* @Var__HspVar13, i32 0, i32 8) ; <i32> [#uses=1] %3 = getelementptr double* %2, i32 %offset ; <double*> [#uses=1] %4 = load double* %3 ; <double> [#uses=1] %5 = fdiv double 1.000000e+000, %4 ; <double> [#uses=1] %ptr2 = load i8** getelementptr inbounds (%struct.PVal* @Var__HspVar71, i32 0, i32 4) ; <i8*> [#uses=1] %6 = bitcast i8* %ptr2 to double* ; <double*> [#uses=1] store double %5, double* %6
最終的にx86命令に落ちると
movl _Var__HspVar43+28, %eax movl (%eax), %esi movl _Var__HspVar13+28, %edi movl $_Var__HspVar13, (%esp) call _HspVarCoreReset movl %esi, 4(%esp) movl $_Var__HspVar13, (%esp) call _HspVarCoreArray2 movsd LCPI89_0, %xmm0 movl _Var__HspVar13+40, %eax divsd (%edi,%eax,8), %xmm0 movl _Var__HspVar71+28, %eax movsd %xmm0, (%eax)
Cに比べるとだいぶ無駄がある。ループのフロー見て配列の自動拡張必要ないことを特定できれば真ん中の当たりは消せるな。
2009-03-24
HSPLetでも AO bench
aobenchの続き。
HSPLetに通してみたらローカル変数のサポートが無かったので適当にでっちあげる。
http://peppermint.jp/products/hsp/hsplet-localvar.patch
関数呼び出しでスタックを積まず再帰はサポートしないって条件のようなのでローカル変数を含めた引数全部をあらかじめフィールドとして全部作っておくように。
http://peppermint.jp/products/hsp/ao.html
同じ環境のJava6で76.8sec
2009-03-23
HSPでAO bench
http://lucille.atso-net.jp/aobench/のコードをHSPに移植してみた。
http://peppermint.jp/products/hsp/ao.hsp
Core2Duo E6850 3GHzで259秒。スクリプト言語的には普通の遅さのよう。
ローカル変数や#deffunc/#defcfunc使わずに全部グローバル変数とgosubで頑張ればもうちょい早くはなりそう。
それはともかく機械生成でデータ込み数千行みたいなのを除けば、初めてHSPで300行越えのコードを書いたけど構造化したりスコープ切ったりするやりかたがよく分からない。
各種命令の使い方やAPIの呼び出し方みたいな解説ページはいっぱいあるんだけど、プログラムの構成の仕方みたいな解説はどこをみればいいんだろう。
2009-03-20
hsp3cnv
半年遅れぐらいだけど、http://dev.onionsoft.net/trac/browser/trunk/hsp3cnv をいじってみる。
extvarへのアクセスと配列の自動拡張対応追加で
http://taillove.jp/mia/のraytracing.hspとかは動くようになった。
ベンチマークとしてレイトレーシングで1回レンダリングするのにかかった時間を図ってみると。
- hsp3.1(オフィシャルで配布されてるもの)
20sec
- hsp3.2 svn head(/Ox&リンク時のコード生成を使用)
17.7sec
- hsp3cnv + hsp3rtest(/Ox&リンク時のコード生成を使用)
15.1sec
- hsp3cnv + hsp3rtest(/O2&リンク時のコード生成なし)
28sec
hsp3cnvが吐くC++のコードはほぼ関数呼び出しだけなのでC++コンパイラ経由せずにネイティブコード生成してJITコンパイラとして使えるようにするのにさほど無茶な手間はかからない気がするけど、上の結果見る限りパフォーマンス向上が得られるかっていうと微妙そう。
