mizuフレームワークにおけるタスクの往復時間は1マイクロ秒未満であり、これは標準的なPythonプロセスプールで典型的な約100 µsのオーバーヘッドと比較して2桁の改善です。この性能向上により、開発者はスレッドと同様の細かさで作業を分散させることができ、わずか10マイクロ秒の小さなタスクであっても並列実行が可能になります。
シリアル化のボトルネックの克服
PythonおよびRにおける標準的なプロセスプールは、各タスクをシリアル化し、ソケットを通じてコピーし、ワーカーによってデシリアル化する必要があるため、大きなオーバーヘッドが発生することがよくあります。タスクが小さい場合、この通信コストが実際の計算時間を上回ることがあり、一方で大きなデータセットは、異なるプロセス間で複数のコピーを作成することでメモリを使い果たす可能性があります。
Mizuは、ロックフリー共有メモリによるプロセス間通信(IPC)を促進するlibmizuと呼ばれるCライブラリを使用することでこれを解決します。データをコピーする代わりに、タスクは両方のプロセスから見えるメモリに一度だけ書き込まれ、ワーカーは追加のオーバーヘッドなしでデータを直接読み取ることができます。
「タスクの往復時間はソケット経由の約100 µsから1 µs未満に低下するため、スレッドと同様の細かさで作業を分割できます」
— GitHub - shikokuchuo/pymizu: Thread-speed async and parallel Python over shared memory
アーキテクチャと性能の向上
このアーキテクチャは、バッチ公開とスピン・ゼン・パーク待機を備えたロックフリーの単一生産者・単一消費者リングを利用しています。この設計により、システムはホットパスにおいてカーネル外に留まり、ピアが死亡したときにのみOS通知をトリガーします。
Apple M4 Proでのベンチマークでは、pymizuがProcessPoolExecutorと比較して、単一ワーカーのパイプラインスループットにおいて135倍の高速化を達成することを示しています。4つのワーカーで2,000の小さなタスクを並列マップする場合、高速化は42倍に達し、実行時間は123ミリ秒からわずか2.9ミリ秒に短縮されました。
言語間の相互運用性
mizuとpymizuは同じCコアを共有しているため、RとPythonのプロセスが直接通信できる統一されたワイヤフォーマットを提供します。これにより、RセッションがPolarsで処理するためにPythonワーカーにデータフレームを渡し、その結果がゼロコピーのALTREPビューとして返されるワークフローが可能になります。
HN Digestによる図(opensource.posit.coの報告数値に基づく)。数値はソースの表記通り。
NumPy配列、Polarsデータフレーム、Arrowテーブルを含む一般的なデータ構造は、マーシャリングや変換なしで境界を越えます。直接送信の方が速い小さなサイズの下限を超えると、これらのオブジェクトは同じメモリページのビューとして共有されます。
現在の制限とライフサイクル
このプロジェクトは現在実験的なライフサイクルにあり、APIはまだ安定しておらず、ユーザーのフィードバックに基づいて変更される可能性があります。64ビットプラットフォーム上のPython 3.10以降が必要であり、拡張機能はインストール中にベンダー提供のCコアをコンパイルします。
プロジェクトが正しく機能するためには、特定のPythonバージョンと64ビットプラットフォームが必要です。
性能の向上は大幅ですが、現在の実装はシングルマシンでの使用を意図しています。プールタスクとしてラムダやクロージャを送信しようとするユーザーは、オプションのcloudpickleエクストラをインストールする必要があります。