Linux カーネル AIO が非同期の「open」システム コールをサポートしないのはなぜですか? 「open」はファイルシステムで長時間ブロックできるため、そうではありませんか?
2 に答える
まず、これはまったく問題のない正当な質問です。反対票は残念でした。おそらく、私よりも知識のある人を追い払ったのでしょう。
AFAICT、正当な理由はありません。あなたが掘り起こした議論は関連性がありますが、まったく満足のいくものではありません (これはおそらくあなたの結論でもあります)。Torvald の主張は技術的には正しいのですが、部屋の中のゾウ (GUI プログラミング) や他の多くのユースケースを明らかに無視しています。
はい、ネットワーク サーバーはネットワーク レイテンシーに拘束されます。他のすべてのIOを気にしない理由になるかどうかは少し疑わしいですが、私はそれを受け入れることができます.
はい、多くのサーバー ワークロードが dentry/inode キャッシュを利用できますが、すべてではないため、常にミスが発生します。
はい、「より多くの RAM を購入する」という議論は機能します。私はそれが良い議論であるとは決して思っていません。
そして、他のすべてのユースケースがあります。GUI プログラミングを含む多くの人にとって、時々または頻繁にブロックすることは問題ではありません。決してブロックすべきではありません。アクセス パターンが非常にランダムで時間が離れている場合は、RAM を追加購入しても効果はありません。ただし、セカンダリ ストレージが提供する容量と同じ容量が必要です。
「とにかく速くなければならない」という考えも間違っています。常にリモートファイルシステムを考慮してください。
唯一の説得力のあるポイントは次のとおりです。
短くて甘い:「aio_open()」は基本的に問題になることはありません。もしそうなら、あなたは何かを誤って設計したか、すべてをシングルスレッド化するのに苦労しすぎています(そして、 代わりに「AIO」と呼ぶだけで、発生するスレッド化を「隠し」ています-要するに、自分自身に嘘をついています)。
ここでのポイントは、まさにスレッド化を回避することなので、この発言には驚かされました。他の議論が列挙されたという単なる事実は、これがあまりにも壊れやすく、単独で立つことができないことを私に示唆しています.
同じ議論を掘り下げると、Mikulas Patocka による次の投稿が見つかります。
FreeBSD や一部の商用 Unice などのカーネル スレッドを使用して非同期 IO をエミュレートできますが、処理する要求と同じ数の (おそらくカーネル) スレッドが必要です。
(...)
実際の非同期 IO を作成するには、すべてのファイルシステムと VFS 全体を _from_scratch_ に書き直す必要があります。それは起こりません。
http://lkml.iu.edu//hypermail/linux/kernel/0102.1/0074.html
これは適切な説明のように思えますが、明らかに良い説明ではありません。
これは古いスレッドであり、それ以来多くの変更が加えられているため、この回答にはほとんど価値がないことに注意してください。ただし、仮説が歴史的aio_open
に利用できなかった理由についての洞察を提供します。また、多くのカーネル ディスカッション (またはその問題に関するプロジェクトの内部ディスカッション) では、通常、すべての参加者が一連の大きな仮定から始めることを期待していることを理解してください。したがって、私がこれを正しく見ていない可能性は十分にあります。
そうは言っても、このビットは興味深いものです (Stephen C. Tweedie):
ああ、でも VMS SYS$QIO でさえ、オープンの実行、IO 要求パケットの割り当て、およびファイルの場所のディスク ブロックへのマッピングにおいて同期的です。データ IO だけが非同期です (Linux 用の Ben の async IO もそれを提供します)。
http://lkml.iu.edu//hypermail/linux/kernel/0102.1/0139.html
なぜ面白いのですか?open
これは、多くの異なるシステム(およびその他の呼び出し) が非同期に実装されていないという概念を強化するためです。さらに、aio_open
POSIX で指定されておらず、その理由を説明する議論が見つかりません。Windows もこの問題を無視しているようです。
それはあたかも間違っているか難しい概念に固有の何かがあるかのようですが、それが最終的になぜなのかについて誰も良い主張をしていないようです.
私の推測では、これは単純に優先度が低く、常にそうでした。事前にスレッド化またはファイルを開くことを含む回避策は、機能を提供するために機能する十分なユースケースにはおそらく十分であり、決して正当化できません.
POSIX がそのような呼び出しを定義しない理由を知ることは興味深いでしょう。ただし、「範囲外」の論理的根拠を期待しています。
この問題の真相を知りたい場合は、LKML などのより適切なチャネルに議論を持ち込む必要があると思います。
Linux ネイティブの aio+O_DIRECT (io_submit、io_getevents) を使用して一連のファイルをコピーする、かなりシンプルでありながら強力な cpaio C ユーティリティを作成しました。できるだけ早くファイルを開き、最初の aio 読み取りをキューに入れ、十分な数のファイル (または、十分な数がない場合はすべて) を開いたら、読み取りの結果のみを探すようにしました。ファイルを非同期で開く方法があればよかったのですが、最終的には大したことではありませんでした。
このツールで数十 TB をコピーしました。
結局、async をオープンにしないのは理にかなっていると思います。これは複雑な操作であり、カーネルは基本的にそれを処理するためにスレッドを起動する必要があります。