4

標準のC++/ C ++ 11(POSIX関数なし)でstd::ifstreamおよびstd::ofstreamの読み取りおよび書き込み速度を最適化する方法は?(1 <-いくつかの質問があるので、これらの数字は異なるポイントを識別します)

バッファの役割が正確にはわからないので、次のことを確認できますか?

  • 読み取り用:ファイルの大部分がメモリにプリロードされます(したがって、バッファサイズがこの大部分のサイズを定義します)(2)
  • 書き込み用:データはメモリに書き込まれ、バッファがいっぱいになると、メモリからファイルシステムに転送されます(3)

std::ifstreamとstd::ofstreamでバッファサイズを設定するにはどうすればよいですか?(4)

私が非常に大きなバイナリファイル(数10 GB)を処理し、ファイルシステムが大規模な読み取り/書き込みに最適であることが多いことを考えると、100 MBのようなバッファサイズを定義できますか?パフォーマンスが低下する場合、なぜですか?(5)

最後に、デフォルトのバッファは、ifstream / ofstreamがファイルに対して読み取り/書き込みを行っているデータの量を検出し、最大速度を提供するようにバッファサイズを調整するという意味で、「スマート」ですか?(6)

4

1 に答える 1

7

バッファリングがどのように機能するかについてのあなたの説明は正しいです、AFAICS。

ただし、1 MBを超えるバッファサイズでは、何も購入できない可能性があります。実際には、スイートスポットはその値をはるかに下回る可能性があります。std::ifstreamディスクキャッシュによって使用され、ディスクキャッシュとstd::ofstreamは関係がないことに注意してください。これはカーネルの仕事であり、独自の裁量で実行されます。ストリームバッファは、1つのシステムコールでカーネルとの間で転送される最大バイト数にのみ影響します。したがって、理想的なバッファサイズは、転送するデータの量に依存しません。何に依存しているのか

  1. システムコールのオーバーヘッドコスト。オーバーヘッドが高いということは、一度により多くのデータを転送する必要があることを意味します。
  2. バッファ管理のオーバーヘッドコスト。どちらかといえば、より大きなバッファの場合はおそらくより大きくなります。
  3. CPUキャッシュのトラッシング効果。小さいバッファを強く支持します。

(1)はより大きなバッファーを優先して機能し、(2)と(3)はより小さなバッファーを優先して機能するため、どこかにスイートスポットがあります。CPUキャッシュサイズは数メガバイト程度になる可能性が高いため、その限界に近づくバッファサイズは(3)の影響が大きく、スイートスポットは確実に1MB程度以下になります。おそらく(2)は無視できるので、バッファサイズの下限を取得するには(1)を見積もる必要があります。システムコールのコストが約1000サイクル程度であり、CPU+メモリの生のコピー速度が4バイト/サイクルであると想定します。4kを転送すると、1つのシステムコールを実行するのと同じくらいの費用がかかります。したがって、バッファサイズが20kの場合、syscallのオーバーヘッドは約20%であり、バッファサイズが100kの場合は約4%です。したがって、理想的なバッファサイズは数百kBの範囲にあります。ファイルサイズに依存しません!。

プロファイリングがパフォーマンスに影響を与えるバッファリングの問題があるという確固たる証拠を提供しない限り、おそらく標準ライブラリの実装を信頼してそれを正しく行うことができます。

于 2012-10-06T10:35:02.660 に答える