3

C/C++ コード (または一般的なコード) のベンチマークについて友人と興味深い議論をしました。getrusage特定のコードの CPU 時間を測定するために使用する単純な関数を作成しました。(特定の機能を実行するのにかかった CPU の時間を測定します)。例を挙げましょう:

const int iterations = 409600; 
double s = measureCPU(); 
for( j = 0; j < iterations; j++ )
        function(args); 
double e = measureCPU(); 
std::cout << (e-s)/iterations << " s \n";

(es) を反復回数で割るべきか、そうでないかという議論がありました。つまり、除算しない場合、結果は許容される形式 (例: 3.0 秒) ですが、除算すると、2.34385e-07 秒のような結果が得られます ...

だからここに私の質問があります:

  1. (es) を反復回数で割るべきですか? そうであれば、なぜですか?
  2. 2.34385e-07 をより人間が読める形式で出力するにはどうすればよいでしょうか? (たとえば、0.00000003 秒かかりました) ?
  3. 最初に関数呼び出しを 1 回行い、その後、反復の CPU 時間を次のように測定する必要があります。

    // first function call, doesnt bother with it at all
    function(args); 
    // real benchmarking
    const int iterations = 409600; 
    double s = measureCPU(); 
    for( j = 0; j < iterations; j++ )
                function(args); 
    double e = measureCPU(); 
    std::cout << (e-s)/iterations << " s \n";
    
4

1 に答える 1

3
  1. 時間を反復回数で割ると、1 つの関数の実行時間の反復に依存しない比較が得られます。反復が多いほど、より正確な結果が得られます。編集: n回の反復に対する平均実行時間。
  2. 分割された時間を1e6で乗算して、1反復単位あたりのマイクロ秒を取得できます(measureCPUが秒を返すと仮定します)

    std::cout << 1e6*(e-s)/iterations << " s \n";
    
  3. @ ogni42が述べたように、forループから測定時間へのオーバーヘッドが発生しているため、ループを少し展開して測定誤差を減らし、反復ごとに8〜16回の呼び出しを行い、さまざまな呼び出し回数を試して方法を確認できます測定時間の変更:

    for( j = 0; j < iterations; j++ ) {
        function(args);
        function(args);
        function(args);
        function(args);
        ...
    }
    
  4. 基本的に得られるのは、数値が低いほど良いということです。より高いスコアリングが必要な場合は、関数のさまざまなバリエーションを測定し、最速のものの時間を取得できます。これで10点取れる。

    score_for_actual_function = 10.0 * fastest_time / time_of_actual_function
    

このスコアリングは時間に依存しないため、さまざまな関数のバリエーションを比較するだけで、関数のスコアが 1 ポイント未満になる可能性があります...ゼロによる除算に注意してください :)

于 2013-07-15T11:59:55.570 に答える