0

さて、malloc で割り当てた char 配列にバイナリ ファイルを読み込んでいます。(ちなみに、ここのコードは実際のコードではありません。実演のためにその場で書いただけなので、ここでの間違いはおそらく実際のプログラムの間違いではありません。) このメソッドは毎秒約 5000 万バイトで読み取ります。

主要

char *buffer = (char*)malloc(file_length_in_bytes*sizeof(char));
memset(buffer,0,file_length_in_bytes*sizeof(char));
//start time here
read_whole_file(buffer);
//end time here
free(buffer);

read_whole_buffer

void read_whole_buffer(char* buffer)
{
  //file already opened
  fseek(_file_pointer, 0, SEEK_SET);
  int a = sizeof(buffer[0]);
  fread(buffer, a, file_length_in_bytes*a, _file_pointer);
}

私が信じているファイルストリームと関数 ReadByte() を使用してファイル全体をバイト単位で読み取るマネージ C++ で同様のものを作成しました。

また、私のコンピュータには sata と IDE ドライブがあり、両方からファイルを読み込んでいますが、まったく違いはありません (SATA は IDE よりもはるかに高速に読み取ると仮定していたので、これは奇妙です) .)

質問

なぜこれが私にとって意味をなさないのか、皆さんは理解できるかもしれません。私の知る限り、バイトごとに読み取るのではなく、ファイル全体を配列に fread する方がはるかに高速です。その上、テストを通じて、マネージ C++ の方が遅いことがわかりました (ただし、コードのベンチマークを行っていて速度が必要な場合にのみ顕著です)。

それで

なぜ私は両方のアプリケーションで同じ速度で読んでいるのか. また、ファイルから配列への 5000 万バイトは高速ですか?

マザーボードがボトルネックになっているのでしょうか?それはあまり意味がないようです。

ファイルを配列に読み込むためのより高速な方法はありますか?

ありがとう。

私の「スクリプトタイマー」

ミリ秒の分解能で開始時間と終了時間を記録します...最も重要なのは、タイマーではないことです

#pragma once
#ifndef __Script_Timer__
    #define __Script_Timer__
    #include <sys/timeb.h>
    extern "C"
    {
        struct Script_Timer
        {
            unsigned long milliseconds;
            unsigned long seconds;
            struct timeb start_t;
            struct timeb end_t;
        };
        void End_ST(Script_Timer *This)
        {
            ftime(&This->end_t);
            This->seconds = This->end_t.time - This->start_t.time;
            This->milliseconds = (This->seconds * 1000) + (This->end_t.millitm - This->start_t.millitm);
        }
        void Start_ST(Script_Timer *This)
        {
            ftime(&This->start_t);
        }  
    }
#endif

バッファのことを読む

char face = 0;
char comp = 0;
char nutz = 0;
for(int i=0;i<(_length*sizeof(char));++i)
{
    face = buffer[i];
    if(face == comp)
        nutz = (face + comp)/i;
    comp++;
}
4

3 に答える 3

1

FILE * APIはバッファリングされたストリームを使用するため、バイトごとに読み取る場合でも、APIは内部的にバッファごとに読み取ります。したがって、比較しても大きな違いはありません。

低レベルのIOAPI(オープン、読み取り、書き込み、クローズ)はバッファリングされていないため、これを使用すると違いが生じます。

FILE * APIの自動バッファリングが必要ない場合は、より高速になる可能性もあります。

于 2009-12-13T13:38:56.693 に答える
1

メイン メモリとの間の転送は、毎秒ギガバイトの速度で実行されます。CPU 内のデータの流れはさらに速くなります。ソフトウェア側で何をしようとも、ハード ドライブ自体がボトルネックのままであることは驚くべきことではありません。

以下は、PerformanceTest 7.0 を使用した私のシステムの数値です。

  • ハードディスク: Samsung HD103SI 5400 rpm: シーケンシャル読み取り/書き込み速度 80 MB/秒
  • メモリ: 3 * 400 MHz で 2 GB DDR3: 約 2.2 GB/秒の読み取り/書き込み

したがって、あなたのシステムが私のシステムよりも少し古い場合、ハード ドライブの速度が 50 MB/秒であっても驚くことではありません。ドライブ (IDE/SATA) への接続はそれほど重要ではありません。これは主に、1 秒あたりにドライブ ヘッドを通過するビット数に関するものであり、純粋にハードウェアの問題です。

心に留めておくべきもう 1 つのことは、OS のファイルシステム キャッシュです。2 回目は、ハード ドライブにまったくアクセスしていない可能性があります。

コメントで言及した 180 MB/s のメモリ読み取り速度は、少し低いように見えますが、それは正確なコードに依存する可能性があります。ここで CPU のキャッシュが機能します。これを測定するために使用したコードを投稿できますか?

于 2009-12-13T12:51:49.957 に答える
0

これについていくつかのテストを行いましたが、ある時点以降、バッファサイズを大きくすると、バッファサイズが大きくなるにつれて効果が低下します。通常、少し試行錯誤することで最適なバッファ サイズを見つけることができます。

また、fread() (より具体的には C または C++ I/O ライブラリ) はおそらく独自のバッファリングを行うことに注意してください。あなたのシステムがそれをサポートしている場合、普通の read() は少し速いかもしれません (またはそうでないかもしれません)。

于 2009-12-13T12:51:43.533 に答える