Next: 実行系の改良
Up: 解析系の改良
Previous: 解析結果の統合と分割コンパイル
図
に示すquick sortでは,qsort/3
の再帰節4を実行する際に,
2回のゴール呼出/復帰が生じる。しかしこのプログラムを
のように変形するとゴール呼出/復帰を1回とすることができる。
図 : プログラム quick sort
- : main :- list1( L ) , qsort2( L,S ),
io :outstream3( [ print(S) , nl ] ).
- : list( L ) :- L =4 [ 27,74,17,33,94 ].
- : qsort( L, R ) :- true | qsort5( L,R,[] ).
- : qsort( [ X | L ],R,R0 ) :- true | partition6( L,X,L2 ),
qsort7( L2,R1,R0 ), qsort8( L1,R,[X | R1] ).
- : qsort( [],R,R0 ) :- true | R =9 R0.
- : partition( [ X | L ],Y,XL1,L2 ) :- X=< Y | XL1 =10 [ X | L1 ],
partition11( L,Y,L1,L2 ).
- : partition( [ X | L ],Y,L1,XL2 ) :- X >=Y | XL2 =12 [ X | L2 ],
partition13( L,Y,L1,L2 ).
- : partition( [],_,L1,L2 ) :- true | L1 =14 [], L2 =15 [].
図 : プログラム quick sortのループ展開
- : main :- list1( L,L,S ),
io : outstream3( [ print( S ),nl ] ).
- : list( L,A,B ) :- L =4 [ 27,74,17,33,94 ], qsort2( A,B ).
- : qsort( L,R ) :- true | qsort5( L,R,[] ).
- : qsort( [ X | L ],R,R0 ) :- true | partition6( L,X,L1,L2,L2,R1,R0 ),
qsort8( L1,R,[ X | R1 ] ).
- : qsort( [],R,R0 ) :- true | R =9 R0.
- : partition( [ X | L ],Y,XL1,L2,A,B,C ) :- X=< Y | XL1 =10 [ X | L1 ],
partition11( L,Y,L1,L2,A,B,C ).
- : partition( [ X | L ],Y,L1,XL2,A,B,C ) :- X >=Y | XL2 =12 [ X | L2 ],
partition13( L,Y,L1,L2,A,B,C ).
- : partition( [],_,L1,L2,A,B,C ) :- true | L1 =14 [], L2 =15 [],
qsort7( A,B,C )
このような変形をプログラムの意味を保存して行なうには,まずゴール
partition
6とqsort
7の実行を逐次化できることが条件となるが,これに
ついてはスレッド化により保証される。したがってqsort
7の直接の
left-siblingであるpartition
6が以下の条件を満たしていることから,意味を
保存したプログラム変形が可能となる。
-
プログラム中の全てのゴール
partition/4
のsuccessorはqsort/3
である。
-
partition/4
から節qsort/3
:4が直接または間接に呼び出されることはない。
このような変形をKLIC標準配布パッケージに含まれる2種のプログラムに適用した結
果,表
に示すようにqsort
, pascal
では 4〜20%
の速度向上が得られた。
プログラム | | org | GS | loop |
qsort |
実行時間[ms] 速度比 GC[回数] |
487 1.00 43 |
477 1.02 24 |
465 1.04 26 |
pascal |
実行時間[ms] 速度比 GC[回数] |
1201 1.00 92 |
1150 1.04 27 |
1000 1.20 36 |
表: ループ展開の効果
Next: 実行系の改良
Up: 解析系の改良
Previous: 解析結果の統合と分割コンパイル
www-admin@icot.or.jp