0

編集:細部をすべて説明するこの長い投稿を書いた後、問題を見つけました...誰かが私が間違っていることと、実行時間を秒単位で取得する方法について良い答えを得ることができれば(5のフロートを使用して)小数点以下の桁数程度)、承認済みとしてマークします。ヒント: 問題は、clock_getttime() の man ページをどのように解釈したかにありました。

やあ、

myOperation実行時間を測定する必要があるという名前の関数があるとします。それを測定するために、コメントの1つでここclock_gettime()で推奨されていたものを使用しています。

私の先生Nは、最終レポートの平均、標準偏差、および中央値を取得できるように、何度も測定することをお勧めします。myOperation M彼はまた、1 回だけではなく、回数を実行することを推奨しています。myOperationが非常に高速な操作である場合、M時間を測定することで、かかる「リアルタイム」の感覚をつかむことができます。使用されているクロックが、そのような操作を測定するために必要な精度を持っていない可能性があります。したがって、実行myOperationが 1 回のみか、それとも 1M回かは、使用しているクロック精度に対して操作自体に十分な時間がかかるかどうかによって異なります。

Mその時の実行に対処するのに問題があります。増加Mすると、最終的な平均値が (大幅に) 減少します。これは私には意味がありません。平均すると、A 地点から B 地点に移動するのに 3 ~ 5 秒かかります。しかし、A 地点から B 地点に移動し、A 地点に戻るのは 5 回です (10 回になります。なぜなら、A 地点から B 地点までは B 地点と同じだからです)。 A) に、あなたはそれを測定します。10 で割るよりも、得られる平均は、ポイント A から B への移動にかかる平均と同じであるはずです。つまり、3 ~ 5 秒です。

これは私のコードでやりたいことですが、うまくいきません。A から B に移動し、A に戻る回数を増やし続けると、そのたびに平均がどんどん低くなっていくので、意味がありません。

十分な理論、これが私のコードです:

#include <stdio.h>
#include <time.h>

#define MEASUREMENTS 1
#define OPERATIONS   1

typedef struct timespec TimeClock;

TimeClock diffTimeClock(TimeClock start, TimeClock end) {
    TimeClock aux;

    if((end.tv_nsec - start.tv_nsec) < 0) {
        aux.tv_sec = end.tv_sec - start.tv_sec - 1;
        aux.tv_nsec = 1E9 + end.tv_nsec - start.tv_nsec;
    } else {
        aux.tv_sec = end.tv_sec - start.tv_sec;
        aux.tv_nsec = end.tv_nsec - start.tv_nsec;
    }

    return aux;
}

int main(void) {
    TimeClock sTime, eTime, dTime;
    int i, j;

    for(i = 0; i < MEASUREMENTS; i++) {
        printf(" » MEASURE %02d\n", i+1);

        clock_gettime(CLOCK_REALTIME, &sTime);

        for(j = 0; j < OPERATIONS; j++) {
            myOperation();
        }

        clock_gettime(CLOCK_REALTIME, &eTime);

        dTime = diffTimeClock(sTime, eTime);

        printf("   - NSEC (TOTAL): %ld\n", dTime.tv_nsec);
        printf("   - NSEC (OP): %ld\n\n", dTime.tv_nsec / OPERATIONS);
    }

    return 0;
}

注:上記のdiffTimeClock関数は、このブログ投稿からのものです。myOperation()長いコードブロックを投稿する必要があるため、実際の関数を投稿しても意味がないため、実際の操作を に置き換えましたmyOperation()。必要に応じて、コードをコンパイルするために好きなものを簡単にコーディングできます。

ご覧のとおりOPERATIONS = 1、結果は次のとおりです。

 » MEASURE 01
   - NSEC (TOTAL): 27456580
   - NSEC (OP): 27456580

OPERATIONS = 100結果は次のとおりです。

 » MEASURE 01
   - NSEC (TOTAL): 218929736
   - NSEC (OP): 2189297

OPERATIONS = 1000結果は次のとおりです。

 » MEASURE 01
   - NSEC (TOTAL): 862834890
   - NSEC (OP): 862834

OPERATIONS = 10000結果は次のとおりです。

 » MEASURE 01
   - NSEC (TOTAL): 574133641
   - NSEC (OP): 57413

さて、私は数学の達人ではありませんが、実際にはそうではありませんが、これは私にはまったく意味がありません. 私はすでにこのプロジェクトに参加している友人とこのことについて話しましたが、彼も違いを理解できません。を増やすと値がどんどん下がっていく理由がわかりませんOPERATIONS。操作自体は、何回実行しても同じ時間かかるはずです (もちろん、平均して、まったく同じ時間ではありません)。

それは実際には操作自体、読み取られるデータ、および一部のデータが既にキャッシュとブラブラにある可能性に依存していると言うことができますが、それは問題ではないと思います。私の場合、myOperationCSV ファイルから 5000 行のテキストを読み取り、値を分離;してデータ構造に挿入しています。反復ごとに、データ構造を破棄して、再度初期化しています。

そういえば、私も での時間の計測に問題があり、clock_gettime()使い方が間違っているのではないかと思います。つまり、最後の例を見てくださいOPERATIONS = 10000。かかった合計時間は 574133641ns で、およそ 0.5 秒です。それはありえない、待っている画面を見て我慢できずに何か食べに行ったので、数分かかりました。

4

4 に答える 4

1

TimeClock 型には、秒用とナノ秒用の 2 つのフィールドがあるようです。ナノ秒フィールドを操作数で割るだけでは意味がありません。合計時間を分割する必要があります。

于 2010-05-12T19:49:09.770 に答える
1

gettimeofday() 関数がある POSIX システムを使用している場合、次のようなものを使用して現在の時刻をマイクロ秒単位で取得できます。

long long timeInMicroseconds(void) {
    struct timeval tv;

    gettimeofday(&tv,NULL);
    return (((long long)tv.tv_sec)*1000000)+tv.tv_usec;
}

これが非常に便利な理由は、関数がどれだけの時間を費やしたかを計算するには、次のことを行う必要があるからです。

long long start = timeInMicroseconds();
... do your task N times ...
printf("Total microseconds: %lld", timeInMicroseconds()-start);

したがって、1 つは秒、もう 1 つはマイクロ秒の 2 つの整数を扱う必要はありません。時間の加算と減算は、明らかな方法で機能します。

于 2010-05-12T20:44:22.913 に答える
1

diffTimeClock()秒数の差を次のように返すように関数を変更するだけですdouble

double diffTimeClock(TimeClock start, TimeClock end) {
    double diff;

    diff = (end.tv_nsec - start.tv_nsec) / 1E9;
    diff += (end.tv_sec - start.tv_sec);

    return diff;
}

メインルーチンdTimeで a に変更しdouble、それに合わせて printfs を次のように変更します。

printf("   - SEC (TOTAL): %f\n", dTime);
printf("   - SEC (OP): %f\n\n", dTime / OPERATIONS);
于 2010-05-12T23:28:36.853 に答える
0

これには通常、time() 関数を使用します。ウォール クロック タイムが表示されますが、最終的に気になるのはそれです。

パフォーマンス テストに関する問題の 1 つは、オペレーティング システムがファイル システム関連の操作をキャッシュする可能性があることです。したがって、2 回目 (およびそれ以降) の実行は、最初の実行よりもはるかに高速になる可能性があります。通常、多くの操作をテストし、結果を平均して、行った変更の結果を把握する必要があります。非常に多くの変数があり、ノイズを除去するのに役立ちます。

于 2010-05-12T19:44:07.370 に答える