1

述語 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

マイクロベンチマークのオーバーヘッドをさらに削減できるかどうか、またはどのように削減できるかについてのアイデアはありますか? ありがとうございました!

4

1 に答える 1

1

寒暖差には注意が必要です。最新の Prolog システムには、ジャスト イン タイム インデックスまたはコンパイルさえあります。そのため、異なる実行が異なる動作をする可能性があります。また、ガベージ コレクションによってタイミングが変動します。

私は常にウォーム ランを測定するので、最初に少なくとも 1 回はベンチマークを実行して、測定を破棄します。そして、もう一度実行して、測定値をメモします。

さまざまなループの変換。通常のアプローチは、ダミーの述語をループに挿入し、ループ時間を測定することによってループ オーバーヘッドを測定することです。そして、後で今度は引きます。ダミー述語は次のように簡単に定義できます。

  dummy.

ループするエバーヘッドが小さいことがわかった場合は、ループのオーバーヘッドを差し引く長さに立ち入らず、測定値がループも測定していることを明確に述べるのも有効だと思います。

同じループを使用すると、引き算をしなくても、ハーネスが実行されるさまざまなテスト オブジェクトの結果を比較できます。

于 2015-04-25T11:41:26.500 に答える