次のような小さなプログラムを作成して、到達不能になったときに目標に使用されたメモリfreeze(X,Goal)
が回収されるかどうかを判断しました。X
%:- use_module(library(freeze)). % Ciao Prolog needs this
freeze_many([],[]).
freeze_many([_|Xs],[V|Vs]) :-
freeze(V,throw(error(uninstantiation_error(V),big_freeze_test/3))),
freeze_many(Xs,Vs).
big_freeze_test(N0,N,Zs0) :-
( N0 > N
-> true
; freeze_many(Zs0,Zs1),
N1 is N0+1,
big_freeze_test(N1,N,Zs1)
).
次のクエリを実行しましょう...
?- statistics, length(Zs,1000), big_freeze_test(1,500,Zs), statistics.
...さまざまなPrologプロセッサを使用して、メモリ消費を調べます。 なんという違いでしょう!
(AMD64) SICStus Prolog 4.3.2 : 使用中のグローバルスタック = 108 MB (AMD64) B-Prolog 8.1 : 使用中のスタック + ヒープ = 145 MB (i386) Ciao Prolog 1.14.2: 使用中のグローバル スタック = 36 MB (AMD64 では ~72 MB) (AMD64) SWI-Prolog 7.3.1 : 使用中のグローバル スタック = 0.5 MB (AMD64) YAProlog 6.2.2: 使用中のグローバルスタック = 16 MB
でさらに反復を実行すると?- length(Zs,1000), big_freeze_test(1,10000,Zs).
、次のような観察結果が得られました。
Ciao Prolog は
{ERROR: Memory allocation failed [in Realloc()]}
中止する前に報告します。sicstus-prologとb-prologは、マシンがフリーズするまで割り当てを増やします。
- swi-prologは、すべての反復を3.554秒で実行します。
- yapもすべての反復を実行しますが、36.910秒かかります。
SWI-Prolog と YAProlog では機能するが、他のものでは機能しない理由はありますか?
実行時間を考えると、SWI-Prolog が YAProlog よりも 1 桁以上優れているのはなぜですか?
私の直感は、「属性変数」と「ガベージ コレクション」の相互作用に傾いています。SWI-Prolog と YAProlog は、他の Prolog プロセッサとは異なる属性付き変数 API と実装を (共有?) 持っています。ありがとうございました!