私は Grand Central Dispatch の大ファンで、最近は Callsdispatch_io_*
ファミリーを見ています。この API がネットワーク I/O (低速、高レイテンシー) にどのように役立つかは簡単にわかります。dispatch_io_create_with_path
つまり、一種の存在は、ローカルファイルシステムでの使用を意味します。(はい、パスがリモート ネットワーク ファイル システム上のリソースを指している可能性があることはわかっていますが、いずれにせよ...) それをいじってdispatch_io_*
みると、単純なブロッキングを使用する場合と比較して、使用するとかなりのオーバーヘッドが発生するように見えることがわかりました。 I/O 呼び出し ( read
,write
など)。この速度低下は主に、ブロックがキュー間でマーシャリングされるときに使用されるカーネル同期プリミティブによるものと思われます。私が試したサンプル ワークロード (非常に多くの I/O バウンド) では、速度低下が 10 倍にもなることがあります。dispatch_io
1つには、おしゃべりな (小さな粒状の) I/O には決して勝てないように見えます。
単一のローカル物理ストレージ ボリュームを持つ単一のマシンの一般的なケースでは、I/O 要求はデバイス レベルで効果的にシリアル化されると思います。そこから、私は次の2つの考えに気づきました。
- ワークロードが CPU バウンドの場合、定義上、データを処理するよりも速く読み書きできます。
- ワークロードが I/O バウンドの場合 (この状況では、1 つのローカルの物理ボリューム) を使用して
dispatch_io
も、ディスクのデータが高速になることはありません。
そこから、この API のスイート スポットは中間にあるのではないかと考えました。つまり、CPU バウンドと I/O バウンドの間で揺れ動くワークロードです。だから私はStackOverflowに尋ねると思いました。
dispatch_io
これらの前提条件 (つまり、単一のマシン、単一のローカル物理ディスク) を使用することでパフォーマンスが大幅に向上する「実際の」ワークフローを説明する最初の回答を受け入れます。