3

x レコードを含むファイルがあるとします。1 つの「ブロック」には m 個のレコードが保持されます。ファイル内のブロックの総数 n=x/m。1 つのレコードのサイズ、たとえば b バイト (1 つのブロックのサイズ = b*m) がわかっている場合、システム コマンド read() を使用して一度に完全なブロックを読み取ることができます (他の方法はありますか?)。さて、このブロックから各レコードを読み取り、各レコードを個別の要素としてベクトルに入れるにはどうすればよいでしょうか。

そもそもこれを行いたい理由は、ディスク I/O 操作を減らすためです。私が学んだことによると、ディスク i/o 操作ははるかに高価です。それとも、ブロックごとに読み取るのではなく、ファイルからレコードごとに読み取り、直接ベクトルに入れるのと同じ時間がかかりますか? ブロックごとに読み取ると、n 個のディスク I/O しかありませんが、レコードごとに読み取ると x I/O になります。

ありがとう。

4

2 に答える 2

3

mmap()を使用してファイルを読み取る代わりに、使用を検討する必要がありますread()

何が優れてmmapいるかというと、あたかもファイルの内容へのポインターが既にあるかのように、ファイルの内容をプロセス空間に単純にマップされたものとして扱うことができるということです。単純にメモリの内容を調べて配列として扱うか、または を使用しmemcpy()てデータをコピーすることで、暗黙的に読み取り操作を実行しますが、必要な場合にのみ実行します。オペレーティング システムの仮想メモリ サブシステムは、非常に効率的に実行できるほどスマートです。

mmap を避ける唯一の考えられる理由は、32 ビット OS で実行していて、ファイル サイズが 2 ギガバイトを超える (またはそれよりわずかに小さい) 場合です。この場合、OS がmmap-ed メモリにアドレス空間を割り当てる際に問題が発生する可能性があります。しかし、64 ビット OS ではmmap、問題なく使用できます。

また、mmap大量のデータを書き込んでいて、データのサイズが事前にわからない場合は面倒です。それ以外は、read.

実際、最新のオペレーティング システムのほとんどは、mmap広範囲に依存しています。たとえば、Linux では、バイナリを実行するために、実行可能ファイルは単純に-ed され、実際にing することなくmmap、あたかも によってそこにコピーされたかのようにメモリから実行されます。readread

于 2013-02-28T06:13:07.593 に答える
2

一度にブロックを読み取っても、必ずしも I/O 操作の数がまったく減るとは限りません。標準ライブラリは、ファイルからデータを読み取るときに既にバッファリングを行っているため、(通常) ストリーム (またはそれに近いもの) から読み取ろうとするたびに実際のディスク入力操作が行われることは期待できません。

一度にブロックを読み取ると、I/O 操作の数が減る可能性があります。ブロックが、ストリームがデフォルトで使用するバッファーよりも大きい場合、データの読み取りに使用される I/O 操作が少なくなると予想されます。一方、ストリームが使用するバッファのサイズを調整するだけで同じことを実現できます (おそらくはるかに簡単です)。

于 2013-02-28T05:57:57.683 に答える