Linux over loopback(127.0.0.1)で最適化されたJavaNIOセレクターを使用していくつかのベンチマークを実行しています。
私のテストはとても簡単です:
- あるプログラムがUDPパケットを別のプログラムに送信し、それが送信者にエコーバックされ、ラウンドトリップ時間が計算されます。次のパケットは、前のパケットが確認されたとき(戻ったとき)にのみ送信されます。ベンチマークが実行される前に、数百万のメッセージによる適切なウォームアップが実行されます。メッセージは13バイトです(UDPヘッダーはカウントされません)。
往復時間については、次の結果が得られます。
- 最小時間:13マイクロ
- 平均時間:19マイクロ
- 75%パーセンタイル:18,567ナノ
- 90%パーセンタイル:18,789ナノ
- 99%パーセンタイル:19,184ナノ
- 99.9%パーセンタイル:19,264ナノ
- 99.99%パーセンタイル:19,310ナノ
- 99.999%パーセンタイル:19,322ナノ
しかし、ここでの落とし穴は、私が100万のメッセージを回転させているということです。
10個のメッセージだけをスピンすると、非常に異なる結果が得られます。
- 最小時間:41マイクロ
- 平均時間:160マイクロ
- 75%パーセンタイル:150,701ナノ
- 90%パーセンタイル:155,274ナノ
- 99%パーセンタイル:159,995ナノ
- 99.9%パーセンタイル:159,995ナノ
- 99.99%パーセンタイル:159,995ナノ
- 99.999%パーセンタイル:159,995ナノ
間違っている場合は訂正してください。ただし、NIOセレクターを回転させると、応答時間が最適になると思われます。ただし、メッセージの間隔を十分に長くしてメッセージを送信する場合は、セレクターを起動する代償を払います。
1つのメッセージだけを送信して遊んでみると、150〜250マイクロの間でさまざまな時間が発生します。
したがって、コミュニティに対する私の質問は次のとおりです。
1-私の最小時間は13マイクロで、この往復パケットテストには平均19マイクロが最適です。私はZeroMQをはるかに上回っているように見えるので、ここで何かが欠けている可能性があります。このベンチマークから、ZeroMQの標準カーネルでの平均時間は49マイクロ(99%パーセンタイル)であるように見えます=> http://www.zeromq.org/results:rt-tests-v031
2-単一またはごく少数のメッセージをスピンするときのセレクターの反応時間を改善するためにできることはありますか?150マイクロはよく見えません。または、本番環境ではセレクターが完全に機能しないと想定する必要がありますか?
selectNow()の周りで忙しいスピンをすることで、より良い結果を得ることができます。少数のパケットを送信することは、多くのパケットを送信することよりもさらに悪いですが、私は現在、セレクターのパフォーマンスの限界に達していると思います。私の結果:
- 単一のパケットを送信すると、一貫した65マイクロの往復時間が得られます。
- 2つのパケットを送信すると、平均で約39マイクロの往復時間が得られます。
- 10個のパケットを送信すると、平均で約17マイクロの往復時間が得られます。
- 10,000パケットを送信すると、平均で約10,098ナノ秒のラウンドトリップ時間が得られます。
- 100万パケットを送信すると、平均で9,977ナノの往復時間が得られます。
結論
したがって、UDPパケットのラウンドトリップの物理的な障壁は平均10マイクロ秒のように見えますが、8マイクロ秒(最小時間)でトリップするパケットがいくつかあります。
忙しい回転で(Peterに感謝)、1つのパケットで平均200マイクロから平均65マイクロまで一貫して移動することができました。
ZeroMQがそれより5倍遅い理由はわかりません。(編集:ループバックを介して同じマシンでこれをテストしていて、ZeroMQが2つの異なるマシンを使用しているためか?)