述語 int_cntA/2 をマイクロベンチマークしたい ...
int_cntA(I,W) :- I >= 0, int_cntA0_cntA(I,0,W).
int_cntA0_cntA(0,W0,W) :- !, W0 = W.
int_cntA0_cntA(I,W0,W) :- I0 is I/\(I-1), W1 is W0+1, int_cntA0_cntA(I0,W1,W).
... 述語 int_cntB/2 に対して:
int_cntB(I,W) :- I >= 0, int_cntB0_cntB(I,0,W).
int_cntB0_cntB(0,W0,W) :- !, W0 = W.
int_cntB0_cntB(I,W0,W) :- I0 is I>>1, W1 is W0+(I/\1), int_cntB0_cntB(I0,W1,W).
良い結果を得るために何を考慮する必要があるかについて 100% 確信があるわけではありません...興味深いディメンションとは何ですか?
これまでのところ、メタコールのパフォーマンスをベンチマークに含めるべきか、それとも生の数値処理に関するものにするべきかという結論に達しました。ループを障害駆動型にするかどうか。実行時に生成されるガベージを気にする必要がありますか?
次のコード スニペットは、単純なベンチマークの実装であり、生のパフォーマンスを目的としており、障害駆動型であり、ガベージを (したがって) 気にしません。
:- use_module(library(between)).
rep_10.
rep_10.
rep_10.
rep_10.
rep_10.
rep_10.
rep_10.
rep_10.
rep_10.
rep_10.
rep_100M :- rep_10, rep_10, rep_10, rep_10, rep_10, rep_10, rep_10, rep_10.
int_cntA/2 のコード:
benchA_1(I,W,Rt) :- statistics(runtime,_),
( repeat(100000000), int_cntA(I,W), false ; true ),
statistics(runtime,[_,Rt]),
int_cntA(I,W).
benchA_2(I,W,Rt) :- statistics(runtime,_),
( between(1,100000000,_), int_cntA(I,W), false ; true ),
statistics(runtime,[_,Rt]),
int_cntA(I,W).
benchA_3(I,W,Rt) :- statistics(runtime,_),
( rep_100M, int_cntA(I,W), false ; true ),
statistics(runtime,[_,Rt]),
int_cntA(I,W).
int_cntB/2 のコード:
benchB_1(I,W,Rt) :- statistics(runtime,_),
( repeat(100000000), int_cntB(I,W), false ; true ),
statistics(runtime,[_,Rt]),
int_cntB(I,W).
benchB_2(I,W,Rt) :- statistics(runtime,_),
( between(1,100000000,_), int_cntB(I,W), false ; true ),
statistics(runtime,[_,Rt]),
int_cntB(I,W).
benchB_3(I,W,Rt) :- statistics(runtime,_),
( rep_100M, int_cntB(I,W), false ; true ),
statistics(runtime,[_,Rt]),
int_cntB(I,W).
SICStus Prolog 4.3.1 を実行している Intel Core i7 Haswell マシンでは、さまざまなベンチマーク方法 (A、B、C) による最悪の場合のパフォーマンスの違いが 100% を超えています。
| ?- benchA_1(0,W,Rt).
W = 0,
Rt = 3140 ?
yes
| ?- benchA_2(0,W,Rt).
W = 0,
Rt = 4130 ?
yes
| ?- benchA_3(0,W,Rt).
W = 0,
Rt = 1960 ?
yes
マイクロベンチマークのオーバーヘッドをさらに削減できるかどうか、またはどのように削減できるかについてのアイデアはありますか? ありがとうございました!