web-dev-qa-db-ja.com

理想的なバッファサイズはどれくらいですか?

重複の可能性:
FileInputStreamを使用するときに理想的なバッファサイズをどのように決定しますか?

C++のistreamファミリのread()またはCのfread()のいずれかを使用してファイル(または任意の入力ストリーム)から生データを読み取る場合、バッファを指定する必要があります。読み取るデータの数。私が見たほとんどのプログラムは、512から4096の間で2の累乗を任意に選択したようです。

  1. それが2の累乗でなければならない/すべきである理由はありますか、それともこれは2の累乗に対するプログラマーの自然な傾向ですか?
  2. 「理想的な」数は何でしょうか? 「理想的」とは、それが最速であることを意味します。基盤となるデバイスのバッファサイズの倍数である必要があると思いますか?または、基になるストリームオブジェクトのバッファの可能性がありますか?とにかく、これらのバッファのサイズをどのように決定しますか?そして、私がそうしたら、それの倍数を使用すると、正確なサイズを使用するよりも速度が向上しますか?

[〜#〜]編集[〜#〜]
ほとんどの答えは、コンパイル時に決定できないということのようです。実行時に見つけても問題ありません。

26
Baruch

ソース:
FileInputStreamを使用するときに理想的なバッファサイズをどのように決定しますか?

最適なバッファサイズは、ファイルシステムのブロックサイズ、CPUキャッシュサイズ、キャッシュレイテンシなどの多くの要素に関連しています。

ほとんどのファイルシステムは、4096または8192のブロックサイズを使用するように構成されています。理論的には、ディスクブロックよりも数バイト多く読み取るようにバッファーサイズを構成すると、ファイルシステムでの操作が非常に非効率になる可能性があります。一度に4100バイトを読み取るようにバッファーを構成しました。各読み取りには、ファイルシステムによる2ブロックの読み取りが必要です)。ブロックがすでにキャッシュにある場合は、RAM-> L3/L2キャッシュレイテンシーの代償を支払うことになります。運が悪く、ブロックがまだキャッシュにない場合は、支払うことになります。ディスクの価格-> RAMレイテンシーも同様です。

これが、ほとんどのバッファのサイズが2の累乗であり、一般にディスクブロックサイズよりも大きい(または等しい)と表示される理由です。つまり、ストリーム読み取りの1つで、複数のディスクブロック読み取りが発生する可能性がありますが、これらの読み取りでは常に完全なブロックが使用されます。無駄な読み取りはありません。

これを保証すると、通常、読み取りと後続の処理の両方に影響を与える他のパフォーマンスに適したパラメータが発生します。データバス幅の調整、DMA調整、メモリキャッシュラインの調整、仮想メモリページの整数)。

19
ravi
  1. 少なくとも私の場合、基礎となるシステムも2の累乗のサイズのバッファーを使用していると想定しているため、試して一致させるのが最善です。最近のバッファーは、「ほとんどの」プログラマーが作成する傾向があるものよりも少し大きくする必要があると思います。たとえば、4KBではなく32KBを使用します。
  2. 残念ながら、事前に知ることは非常に困難です。たとえば、アプリケーションがI/OまたはCPUバウンドのどちらであるかによって異なります。
4
unwind
  1. ほとんどの場合、「丸め」の数値を選択するだけだと思います。コンピュータが10進数で動作する場合、1024または8192ではなく1000または10000を選択する可能性があります。非常に正当な理由はありません。

考えられる理由の1つは、ディスクセクターのサイズが通常512バイトであるため、すべてのハードウェアレイヤーとキャッシュによって低レベルのコードが実際にこの事実を効率的に使用できると仮定すると、その倍数を読み取る方が効率的です。これは、デバイスドライバーを作成するか、バッファーなしの読み取りを実行しない限り、おそらく不可能です。

1
jcoder

1。それが2の累乗でなければならない/すべきである理由はありますか、それともこれは2の累乗に対するプログラマーの自然な傾向ですか?

あんまり。これはおそらく、メモリコピーを簡素化するためにデータバス幅のサイズにも収まるものであるはずなので、16に分割するものはすべて現在のテクノロジで問題ありません。 2の累乗を使用すると、将来のテクノロジーでうまく機能する可能性が高くなります。

2。 「理想的な」数は何でしょうか? 「理想的」とは、それが最速であることを意味します。

最速は可能な限りです。ただし、数キロバイトを超えると、使用するメモリの量と比較してパフォーマンスの違いはごくわずかになります。

基盤となるデバイスのバッファサイズの倍数である必要があると思いますか?または、基になるストリームオブジェクトのバッファの可能性がありますか?とにかく、これらのバッファのサイズをどのように決定しますか?

基になるバッファのサイズを実際に知ることはできません。または、それらが同じままであることに依存することもできません。

そして、私がそうしたら、それの倍数を使用すると、正確なサイズを使用するよりも速度が向上しますか?

いくつかありますが、ごくわずかです。

0
Guffa

バッファの理想的なサイズは、ハードドライブ内の1ブロックのサイズであると思います。そのため、ハードドライブからデータを保存またはフェッチするときに、バッファと適切にマッピングできます。

0
Rup

それが2の累乗でなければならないことを私が知っている理由はありません。バッファサイズがmaxsize_t以内である必要があるという制約がありますが、これが問題になる可能性はほとんどありません。

明らかにバッファが大きいほど良いですが、これは明らかにスケーラブルではないため、コンパイル時またはできれば実行時にシステムリソースの考慮事項を考慮する必要があります。

0
Component 10