0

を使用して、クラスで 2 台の外付け HDD の帯域幅を測定してきましたgettimeofday

驚くべきことに、何度か繰り返した後 (実行ごとに 3 回の測定を 3 回実行)、両方の HDD で 2500MB のファイルを書き込む方が小さいファイルを書き込むよりも高速であることがわかりました。

帯域幅チャート

これが私たちの C コードです。いくつかのチャートを生成するために Python スクリプトから呼び出されます。

//argv[1] = path, argv[2] = size in MB (2500 in this case)

#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#include <fcntl.h>


struct timeval tv0;
struct timeval tv1;

int main(int argc, char *argv[]){
    unsigned long size=atoi(argv[2])*1000L*1000L;
    int f = open(argv[1], O_CREAT|O_WRONLY|O_TRUNC, 0777);
    char * array = malloc(size);
    gettimeofday(&tv0, 0); //START TIME
    write(f, array, size);
    fdatasync(f);
    close(f);
    gettimeofday(&tv1, 0); // END TIME 
    double seconds = (((double)tv1.tv_sec*1000000.0 + (double)tv1.tv_usec) - ((double)tv0.tv_sec*1000000.0 + (double)tv0.tv_usec))/1000000.0;
    printf("%f",seconds);
}

先生は知りませんでしたので、ここで質問します。これが起こる理由はありますか?

4

1 に答える 1

1

あなたのベンチマークには深刻な欠陥があります:

  • すべての関数呼び出しがエラーなしで成功することを確認せずに想定します。
  • 成功すると、指定されたバイト数全体が書き込まれると想定write()されますが、これが保証されるわけではありません。

どちらも、仮定が満たされないことが判明した場合、ベンチマークの結果を簡単に無効にする可能性があり、少なくとも 2 つ目はそのようになる可能性がかなり高いです。

write()は特に、書き込まれたバイト数を として返すことに注意してくださいssize_tssize_t特定の幅がシステムに依存する符号付き整数型です。サイズが 32 ビットの場合、1 回の呼び出しで 2500MB のバッファすべてを書き込むwrite() ことはできません。これは、符号付き 32 ビット整数が表現できるバイト数よりも多いためです (制限は 2100 MB を少し超えています)。

さらに、プログラムは、非常に大きなメモリ ブロックを正常に割り当てることができると想定していますが、そうではないことが簡単に判明する可能性があります。ただし、この仮定が失敗した場合は、おそらくクラッシュが報われるでしょう。

于 2016-04-04T19:31:23.327 に答える