2011-07-07 16 views
3

将来の使用のために、たくさんのデータをバッファリングする必要があります(GB単位)。 このような膨大な量のデータをバッファリングするのに十分なRAMがないため、データをファイルに格納することにしました。ファイルへのデータ書き込み:fflush()に多くの時間がかかります

ここでの落とし穴は、データをファイルに書き出している間に、他のスレッドがその "バッファされた"データを必要とすることがあるため、何か書き込むたびにファイルストリームをフラッシュしなければならないということです。正確には、データは(TiVoのような)あらかじめ記録されたデータとしてバッファリングするビデオフレームです( )。他のスレッドは、特定の時点で書き込むこともあれば書きたくないかもしれませんが、そうしたときにファイルからfreadフレームを処理する。

一般的なケースでは、fwrite - fflushのコンボは約150μsですが、ときどき(かなり公然)、コンボは1.5秒以上かかります。私はリアルタイムでフレームを処理しなければならないので、これを買う余裕はありません。

私はここで多くの質問があります。

  1. は、ファイル内のバッファリングデータの私のアプローチは正しいですか?どのような選択肢がありますか?

  2. なぜfwrite-fflush操作が突然何らかの機会に時間がかかる理由はありますか? 1.5秒を1回服用した後、150μsに戻ります。

答えて

2

#2:ほとんどの現代のファイルシステムでは、今日の巨大なHDのディレクトリおよびデータノードの量を管理するためにbtreeアプローチを使用しています。すべてのツリーと同じように、時にはバランスをとる必要があります。それが起こっている間、変更は起こらなければならないので、システムがロックアップする理由です。通常、OSの巨大なキャッシュのために大したことではありませんが、あなたは痛いコーナーケースです。

あなたはそれについて何ができますか? (すなわち、ディスクに書き込まないか、それをディスクに書き込むために独立したプロセスを使用しない)RAM内の最後のNフレームを通信し、維持するための

  1. 利用ソケット:2つの方法があります。

  2. 新しいファイルを書き込まないでください。は、既存のファイルを上書きします。すべてのデータブロックの位置は事前に分かっているので、書き込む間はFSに再編成されません。それはまた少し速くなります。つまり、巨大なファイルを作成したり、rawパーティションを使用して上書きしたりすることです。ファイルの終わりに達すると、最初に戻り、繰り返します。

欠点:

アプローチ#1を使用すると、フレームを失うことができます。また、すべてのクライアントが十分に高速でデータを読み取り、処理できること、またはサーバーがブロックする可能性があることを絶対に確認する必要があります。

#2では、現在の「ファイルの終わり」がどこにあるかを読者に伝える方法を見つける必要があります。

そのため、おそらく混合アプローチが最善です:

  1. は、巨大なファイル(数GB)を作成します。 1つのファイルで十分でない場合は、いくつかを作成します。
  2. ソケットを開く
  3. データをファイルに書き込みます。ファイルの最後に到達した場合は、0の位置に移動してそこに書き込みを続けます(循環バッファのように)。
  4. フラッシュデータ
  5. ソケット

メモリマップドファイルを使用することを検討してください経由で読者に新しいデータの開始と量を送信します。それはすべてをもう少しシンプルにするでしょう。

+0

メモリマップファイルの使用に関するコメントに関して、数GBのファイルをメモリにマップできますか?私は512 MBのRAMを持っています。また、どのようにしてメモリマッピングが簡単になりますか? – puffadder

+0

はい、あなたのCPUアドレス空間がそれを処理できる限り、ファイルサイズは重要ではありません。 32ビットCPUの場合、約3.5GBのファイルを64ビットCPUで管理できますが、ファイルサイズは関係ありません。シンプルなもの:http://en.wikipedia.org/wiki/Memory-mapped_file基本的には、メモリ内のバイト配列のようにファイルにアクセスすることができます。 –

1

RAMとディスクのほかに、実際には他のオプションはありませんが、バリエーションはありません。私はアプローチが健全だと思う:あなたは本当に良いファイルシステムのパフォーマンスを得ている。

余分な空き領域を探しているファイルシステム(短いリストが維持されていますが、使い果たされた場合はより高価な検索が必要です)が余分な時間を費やしている可能性があります。これが原因の場合は、ファイルを最大サイズで事前に割り当ててからランダムなI/O(fopen (fn, "r+"))を使用してファイルに書き込んで、ファイルの長さを切り捨てないようにします。

ファイルI/O時間を安定させるのに役立つ別の手法は、各フレームバッファをセクタ境界に整列されたファイルオフセットに書き込むことです。このようにして、ファイルシステムは、上書きされないものを保存するためにセクタから最初に読み出すことによって、奇妙にオフセットされた書き込み操作を処理する必要はありません。

関連する問題