オペレーティングシステムへの単一の大規模な読み取り/書き込み要求は、複数の小さな読み取り/書き込み要求よりも安いですか?

オペレーティングシステムへの単一の大規模な読み取り/書き込み要求は、複数の小さな読み取り/書き込み要求よりも安いですか?

公式文書によると、JavaがBuffered Streamsを実装する理由の1つは次のとおりです。

これまでに見たほとんどの例では、バッファリングされていないI / Oを使用していました。つまり、すべての読み取りまたは書き込み要求は、基本オペレーティングシステムによって直接処理されます。これらの要求は通常、ディスクアクセス、ネットワーク活動、または他の比較的高価な操作を引き起こすため、プログラムの効率が大幅に低下する可能性があります。

源泉:https://docs.oracle.com/javase/tutorial/essential/io/buffers.html

複数の小さな読み取り/書き込み要求と比較して、Linux上の単一の大規模な読み取り/書き込み要求は実際に高価ですか?前者は後者に比べてどのくらい効率的ですか?

答え1

そこのテキストは、アプリケーション内のバッファリングを意味すると思います。これは通常Cライブラリによって行われます。たとえばgetchar()、電話をかけるgetchar()と、プロセス内のバッファからデータを返すことは、ユーザーモードからカーネルモードに切り替える必要があるシステムコールよりはるかに高速です。

複数の小さな読み取り/書き込み要求と比較して、Linux上の単一の大規模な読み取り/書き込み要求は実際に高価ですか?

大規模な要求は複数の小さな要求によるオーバーヘッドを節約し、コストが安くなる可能性があります。しかし、このアイデアはどこで得ましたか?大小の要求に言及するリンクされた文書は見えませんか?

答え2

ディスクブロックは通常オペレーティングシステムによってキャッシュされるため、ほとんどの短い読み書きにデバイスに直接アクセスする必要はありません。さらに、オペレーティングシステムは通常、2つの連続したブロックを読み取るときにそれを認識し、次のブロックに対してプリエンプティブ先読みを実行するため、必要に応じてすでにキャッシュされています。

ただし、重要な追加のパフォーマンスの問題があります。プロセスがシステムコールを実行すると、実行する準備が整った他のプロセスにCPUが提供されます。システムコールが満たされると、プロセスはスケジューラキューに入り、ターンが実行されるのを待ちます。 CPUが多いプロセスが混在している場合は、スケジュールされるたびに最大時間フラグメントが使用され、プロセスはアクセスするたびにその時間フラグメントよりも遅れます。

関連情報