Open2

Optimize signal sending to processes with message_queue_data=off_heap enabled #5020 メモ

voluntasvoluntas

DeepL Pro による翻訳

Erlangでは1つのプロセスから他のプロセスに送られるシグナル(つまりメッセージシグナルと非メッセージシグナル)は送信順に並べられることを保証しています。しかし、異なるプロセスから特定のプロセスに送られるシグナルには順序付けの保証がありません。そのため、複数のプロセスが特定のプロセスに対して、互いに同期を取らずに並行して信号を送信することができます。しかし、このようなシグナル送信は、送信側が受信側プロセスの外側のシグナルキューのロックを取得する必要があるため、従来は常にシリアル化されていました。今回のコミットにより、message_queue_data=off_heap設定(1)を有効にしたプロセスに対して、複数のプロセスが互いに干渉することなく並行してシグナルを送信できるようになりました。このパラレルシグナル送信の最適化により、シグナル送信のスケーラビリティが従来に比べて格段に向上しました(2)。

(1) message_queue_data=off_heapの設定を有効にする方法については、関数erlang:process_flag/2とerlang:spawn_opt/4のドキュメントにあります。

(2) http://winsh.me/bench/erlang_sig_q/sigq_bench_result.html

実装方法

シグナル送信の並列化は、message_queue_data=off_heapの設定が有効なプロセスでのみ動作します。message_queue_data=off_heap設定が有効になっているプロセスでは、新しい最適化はヒューリスティックな手法に基づいて必要に応じて有効になったり無効になったりし、最適化が不要な場合にはわずかなオーバーヘッドが与えられます。この最適化は、外部メッセージキューのロックに対するコンテンションが高い場合に有効になります。また、フェッチ・オペレーション(外側のメッセージ・キューから内側のメッセージ・キューにメッセージをフェッチすること)ごとにエンキューされたメッセージの数が少ない場合には、最適化は解除されます。

この最適化が有効な場合、外側のメッセージ・キューには、送信プロセスがシグナルをエンキューするシグナル・バッファの配列があります。受信側のプロセスが外側のメッセージ・キューからメッセージをフェッチする必要がある場合には、空でないバッファの内容が外側のメッセージ・キューに追加されます。各プロセスには、バッファ配列内の特定のスロットが割り当てられます(特定のスロットへのハッシュにはプロセスIDが使用されます)。これにより、システムは同じプロセスから来るメッセージ間の送信順序を保持することができます。