lmntalからc言語への変換の設計と実装
DESCRIPTION
LMNtalからC言語への変換の設計と実装. 2007年度卒業論文発表. 2008/2/5. 1G04R013-7. 石川 力. LMNtalとは. ルールによる階層グラフ構造の書き換えで計算が進む言語. ルールの実行順序は自由. →可能なところから計算が進む並行計算のモデル. X=[a,a,a], {p(X,[])}. X=[], {p(X,[a,a,a])}. →. X=[a|T], {p(X,Y), $p[Y]} :- {p(T,M), {M=[a|Y],$p[Y]}}. LMNtal実行までの処理の流れ. 中間命令列が各処理の中心にある. - PowerPoint PPT PresentationTRANSCRIPT
1
LMNtalから C言語への変換の設計と実装
2008/2/5
1G04R013-7
2007年度卒業論文発表
石川 力
2
LMNtalとは
ルールの実行順序は自由 →可能なところから計算が進む並行計算のモデル
→
X=[a,a,a], {p(X,[])}.
X=[a|T], {p(X,Y), $p[Y]} :- {p(T,M), {M=[a|Y],$p[Y]}}.
ルールによる階層グラフ構造の書き換えで計算が進む言語
X=[], {p(X,[a,a,a])}.
3
LMNtal実行までの処理の流れ
中間命令列が各処理の中心にある
4
中間命令列
findatom
deref
func
newatom
newlink
freeatom
グラフの始点を選ぶリンクをたどる
アトムの種類を確認する新しいアトムを生成するリンクを張るアトムを消す
[1, 0, 'a'_1]
[2, 1, 0, 0]
[2, 'b'_1]
[3, 0, 'c'_1]
[1, 0, 3, 0]
[2]
(1)
(2)
(3)
(4)
(5)
(6)
以下の例は概念を示すためのもので実際の中間命令列とは異なっている
中間命令列とは、グラフを操作するための粒度の小さい命令セットである
5
研究の動機・目的
* SLIMは Java版実行時処理系と比較して数十倍高速
* Java版実行時処理系において、 Javaへの変換を行うと インタープリット実行に比べ数倍高速
SLIM上において Cへの変換を行う
ここに Java版で得られた高速化の手法を持ち込むことで更なる高速化
より速い LMNtal実行環境を得ること
SLIMは軽量・高速な実行時処理系を目指し多くの改良が施されている
・ リンクオブジェクトの排除
・ ポインタメンバへのデータの埋め込み ・ 内部データ構造の絞込み
↓
6
findatomテンプレート
i ? = lmn_mem_get_atomlist(? , ? );
t ? = ?for ( ? = atomlist_head(i? );
? != atomlist_end(i? ); ? = atom_next(? ) )
{繰り返す内容
}失敗時命令
変換の流れfindatomdereffunc
newatomnewlinkfreeatom
[1, 0, 'a'_1][2, 1, 0, 0][2, 'b'_1]
[3, 0, 'c'_1][1, 0, 3, 0][2]
i1 = lmn_mem_get_atomlist(v0, 'a'_1);
t1 = 'a'_1;for ( v1 = atomlist_head(i1);
v1 != atomlist_end(i1);v1 = atom_next(v1) )
{if(LMN_ATOM_GET_ATTR(v1,0) != 0)
continue;・・・
}return 0;
long v1, a1; /* アトムが入る */long v2, a2; /* アトムが入る */・・・
変換前
変換後
1.中間変数を出力
2.各中間命令を対応する
Cソースコードに変換
3.補助変数に型情報を出力
7
1.中間変数の出力各中間命令が使用する中間変数を関数の先頭で宣言する
Javaへの変換機では中間変数を基底クラスのポインタ配列で管理し、使用する際にはその要素に静的なキャストを行っていた
Cへの変換機では、最適化が効きやすいよう変数をばらばらにし、最終的には各変数に静的な型を持たせられるようにした。現在は汎用型ポインタと整数データのみが利用可能である。
この方法を用いることで、 doubleのようにサイズの大きな一時データを扱うことも期待できる
Object[] v = new Object[100];
Atom *v1, *v2, *v4; Membrane *v3; int v5;
SLIMでのインタプリタでも汎用の変数によって同様の方法を用いていた
LmnWord *v = malloc(100*sizeof(LmnWord));
8
2.中間命令に対応する C言語コードを出力各中間命令を実行するための C言語コードを出力する
しかし SLIMで設計変更した影響により、中間命令と実行コードが対応しない場合がある
そのような場合出力処理が煩雑になりがちである
この問題を解決するため、「中間命令に対応する C言語コードを出力する関数」を出力する補助ツールを作成した
if ( リンクの先がデータなら ) {代入によるデータコピー
} else {専用関数によるデータコピー
}
#ieq v vif(! (TRANS_DATA($$0) == TRANS_DATA($$1))) $$f;
この記述は、中間命令 ieqに対して出力するコードを表現しており、変数 0と変数 1が等しくなければ次の繰り返しを行う
freemem [ 1 ] ⇒ lmn_mem_free(v1);
loadruleset [ 0, 3 ] ⇒ lmn_mem_add_ruleset(v0, (void*)&trans_ruleset_3);
9
3.補助変数への型出力SLIMにおいてはデータ構造の設計上アトムの種類 (型 )が分からないとそのアトムのリンクを参照できないしかし機械的な変換では各命令にアトムの種類の情報が含まれていないため動的に型を調べるしかなかった
⇒型を解析して静的に種類が分かっている場合は無駄を回避したい
newatom [1, 0, 'a'_1] ⇒ v1 = newatom('a'_1); t1 = 'a'_1;
中間命令列において、ある中間変数の型が予測できる時があれば、その時補助変数の内容は定数性を持っているはずである
自前で型解析を行わないでもC言語コンパイラの定数の畳み込み最適化を利用することで型に関する最適化を行える
そこで型を表す補助変数を用意した
↓
10
C言語への変換の効果
11
まとめと今後の課題
C言語コンパイラの最適化を利用することでルール内の最適化を行いある程度実用的な例では SLIMでのインタープリット実行に比べ3倍程度の高速化を得られた。
今回 C言語に変換したのはルール内のみで、実行方式については自然な C言語とはかけ離れている。LMNtalプログラムにおいて C言語に近い記述をしていればそれに似た実行方式をとる自然な C言語コードを出力できるようにしたい。
LMNtalから C言語への変換機能を設計、実装した。
速度面では、中間命令を操作しないルール内でのこれ以上最適化は難しく、中間命令列をルールの全体の意味を考慮して最適化するか、ルールの境界を越えた最適化を行う必要がある。
12
参考
[1] 乾敦行,工藤晋太郎,原耕司,水野謙,加藤紀夫,上田和紀 :
``階層グラフ書換えモデルに基づく統合プログラミング言語
LMNtal''
コンピュータソフトウェア, Vol.~25, No.~1, pp.124--150,
2008.[2] 石川力 , 堀泰祐 , 村山敬 , 岡部亮 , 上田 和紀 :
``軽量な LMNtal実行時処理系 SLIMの設計と実装 ''
情報処理学会第 70回全国大会 (発表予定 ), pp.??--??, 2008.
13おわり
14
findatom
deref
func
newatom
newlink
freeatom
[1, 0, 'a'_1]
[2, 1, 0, 0]
[2, 'b'_1]
[3, 0, 'c'_1]
[1, 0, 3, 0]
[2]
(1)
(2)
(3)
(4)
(5)
(6)
(1)
(2)
(3)
(4)
(5)
(6)
foreach(v1 in 'a'_1){
if( v1.attr[0] != 0 ){ continue; } else { v2 = v2.link[0]; }
if( v2.func != 'b'_1){ continue; }
v3 = newatom('c'_1);
newlink(v1, 0, v3, 0);
freeatom(v2);
}
/* success */
/* failure */
この中間命令列は次のように機械的に変換が可能である
以下のソースコードも説明のための概念的なもの
15
変換の流れ
*使用される文字列、型等の静的な情報を それぞれ配列として出力
*各ルールを関数として出力
+ルール内で使用される中間変数を出力
+各中間命令に対応する C言語コードを出力 ・ その際に変数の型を補助変数に出力
char *trans_symbols[] = {
"lmn",
"tal",
"slim"
};
int trans_rule_0_0()
{
int v0d, v0a;
・・・
}
int trans_rule_1_0()
{
・・・
}
・ 変数の使用目的に合わせた型で宣言
16
SLIMにおいてはデータ構造の設計上アトムの種類 (型 )が分からないとそのアトムのリンクを参照できないしかし機械的な変換では各命令にアトムの種類の情報が含まれていないため動的に型を調べるしかなかった
⇒型を解析して静的に種類が分かっている場合は無駄を回避したい
newatom [1, 0, 'a'_1] ⇒ v1 = newatom('a'_1); t1 = 'a'_1;種類が予測できる時は型を表す変数の中身が一意に決まるはずなので、型検査を C言語コンパイラが最適化してくれる
自前で型解析を行わないでも C言語コンパイラの最適化を利用できる
型を表す補助変数を用意する
↓
17
C言語への変換の効果
ルール実行の失敗が多い場合や、各ルールの長さが短い場合ボトルネックが最適化の範囲の外のためあまり効果がえられない
例 ) 単純なアトムの確保 /開放を繰り返す場合
3.775
2.414
インタープリット実行C言語変換
それに対し、ルールが複雑になると最適化の効く範囲が実行時間に占める割合が増えるため効果が高くなる
例 ) lambda計算 (Church数の例題 )
3.775 (s)
2.414
インタープリット実行C言語変換
13.098
4.827
インタープリット実行C言語変換
インタープリット実行C言語変換