背景:の潜在的なパフォーマンス向上には非常に興味がありますio_uring
が、意味のあるベンチマークを実装するには、C、Linux カーネル、ブロック デバイスの内部動作に関する十分な知識がありません。私が求めているのは、具体的な数値ではなく、今後の研究に役立つアーキテクチャの概要だけです。
10 個の 4 バイト整数のバッチを繰り返しファイルに追加し、それを同期するプログラムがあるとします。代わりに、バッチ内の各整数を独自のファイルに追加するモデルに切り替えます。つまり、10 個のファイルのそれぞれに 1 つの 4 バイト整数を書き込み、それらすべてを同期します。
同期IOを使用すると、元のスキームでは2つのシステムコール(1つの書き込み+ 1つの同期)を使用し、int-per-fileアプローチではなんと20(10の書き込み+ 10の同期)を使用します。システムコールの点では、節約はio_uring
莫大です。1回の送信で20のシステムコールに相当するものを達成できますio_uring
。私にとって不明瞭なのは、休むwrite
提出が完了すると、Linux マシンの規模は拡大します。
- ほとんどのディスクには、並列書き込みに対するハードウェア サポートがある程度備わっていますか? あるいは、SSD にはあっても、回転ディスクにはないのでしょうか?
- 書き込みはディスクにパイプライン化(バス経由?)されるので、カーネルは書き込みごとに往復応答を待つ必要はありませんか?
- カーネル自体は、 経由で要求されたすべてのシステムコールをキューに入れることになりますか
io_uring
? - 考慮していない他のボトルネックはありますか?
私のメンタルモデルが間違っている可能性もあります。ご指摘いただければ幸いです。
答え1
ほとんどのディスクには、並列書き込みに対するハードウェア サポートがある程度備わっていますか? あるいは、SSD にはあっても、回転ディスクにはないのでしょうか?
ほぼすべてのディスクは、回転式かソリッド ステートかに関係なく、同じです (回転式ディスクでもキャッシュがあるため、少量のデータであればそれほど遅くないように見えます)。安価な USB キーや SD カードでは同時実行性は低くなりますが、ある程度の並列処理は可能です... 単一デバイスの最大並列コマンド数に関して言えば、SATA は最大 32、SCSI は 10 から 100、NVMe は 1000 まで可能です (仕様では最大 65536 に制限されていると思いますが、そこまで高いデバイスはまだ知りません)。
書き込みはディスクにパイプライン化(バス経由?)されるので、カーネルは書き込みごとに往復応答を待つ必要はありませんか?
はい、複数の書き込み (または読み取り) を並行して送信できます。ただし、これが発生するかどうかは多くの要因に依存します (たとえば、カーネルが効率化のためにそれらをグループ化する場合や、同期が必要なためキューを空にする必要がある場合など)。
カーネル自体は、io_uring 経由で要求されたすべてのシステムコールをキューに入れることになりますか?
おそらく、io_uring
ブロックされない場合はI/Oをインラインで完了し、そうでない場合はキューに入れられます。io_uringによる効率的なIO: 「さらに重要なのは、ブロックされない操作の場合、データはインラインで提供されることです」。
考慮していない他のボトルネックはありますか?
はい。また、次のような利点を実際に確認できるほど十分な I/O を 1 秒あたりに実行しているかどうかも不明ですio_uring
。さらに、頻繁な同期は、頻度と実行方法に応じて並列処理を制限する可能性があります。バッファリングされた I/O を実行している場合、カーネルは RAM に書き込んでいるため、同期でも並列処理を絞り出し、可能な場合は RAM から並列にデステージします。(前の項目は網羅的なリストではないことに注意してください)
(タイトルからの質問)
同時書き込みは io_uring によってどの程度拡張できますか?
使用しているカーネルとI/Oの送信方法に応じて、OKから非常に良い結果になります。この中の参考文献とリンクを参照してください。「Linux には本当に非同期ブロック I/O はないのか?」に対する回答。
参考文献
- ブロックレイヤーの紹介- ブロック層について語る2部構成のシリーズ
- Linux ブロック IO: マルチコア システムでのマルチキュー SSD アクセスの導入- Linux マルチキューの変更のアーキテクチャを説明する論文
- のLinux ブロック I/O 層の紹介YouTubeビデオプレゼンテーション