私のアプリケーションには、独自のスレッドで情報を処理するサービスがいくつかあります。それらが完了すると、次のサービスにメッセージを投稿し、次のサービスは独自のスレッドで作業を続けます。メッセージの引き渡しは、LinkedBlockingQueue を介して行われます。通常、ハンドオーバーには 50 ~ 80 マイクロ秒かかります (キューにメッセージを入れてからコンシューマーがメッセージの処理を開始するまで)。最も重要なサービスのハンドオーバーを高速化するために、ブロッキング アプローチの代わりにビジー スピンを使用したいと考えました (12 個のプロセッサ コアがあり、これらの重要なサービスに 3 個を割り当てたいと考えています)。だから.. LinkedBlockingQueue を ConcurrentLinkedQueue に変更しました
そしてやった
for(;;)
{
Message m = queue.poll();
if( m != null )
....
}
その結果、最初のメッセージ パスに 1 マイクロ秒かかりますが、次の 25 回のハンドオーバーで遅延が増加し、500 マイクロ秒に達し、その後、遅延が突然 1 マイクロ秒に戻り、増加し始めます。レイテンシが 1 マイクロ秒で開始し、500 マイクロ秒で終了する 25 回の繰り返しのサイクル。(メッセージは毎秒約 100 回渡されます)
平均レイテンシが 250 であるため、私が求めていたパフォーマンスの向上とはまったく異なります。
また、ConcurrentLinkedQueue の代わりに LMAX Disruptor リングバッファを使用しようとしました。そのフレームワークには、ビジー スピンの実装とまったく異なるキューの実装で独自のビルドがありますが、結果は同じでした。だから、キューや私が何かを悪用したせいではないことは確かです..
質問は..ここで一体何が起こっているのですか? この奇妙なレイテンシ サイクルが表示されるのはなぜですか?
乾杯!!