問題タブ [cyclicbarrier]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
4 に答える
4716 参照

java - java.concurrency.CyclicBarrier を期待どおりに動作させるにはどうすればよいですか

2 つのスレッドを生成し、CyclicBarrier クラスを使用してそれらが同期するのを待つコードを書いています。問題は、循環バリアが期待どおりに機能せず、メイン スレッドが個々のスレッドの終了を待機しないことです。私のコードは次のようになります。

私が間違っていることは何ですか?または、これらのバリア同期メソッドを記述するより良い方法はありますか? 助けてください。

0 投票する
6 に答える
4168 参照

java - Java で最も高速な周期的同期は何ですか (ExecutorService と CyclicBarrier と X)?

以下に概説するような固定数のスレッドを使用した同時反復処理シナリオで最高のパフォーマンスを提供する可能性が高い Java 同期構造はどれですか? しばらく自分で (ExecutorService と CyclicBarrier を使用して) 実験し、その結果に少し驚いた後、専門家のアドバイスや新しいアイデアをいただければ幸いです。ここでの既存の質問は、主にパフォーマンスに焦点を当てているようには見えないため、この新しい質問です。前もって感謝します!

アプリのコアは単純な反復データ処理アルゴリズムで、OS X 10.6 と Java 1.6.0_07 を実行している Mac Pro の 8 つのコアに計算負荷を分散するために並列化されています。処理されるデータは 8 つのブロックに分割され、各ブロックは Runnable に送られ、固定数のスレッドの 1 つによって実行されます。アルゴリズムの並列化はかなり簡単で、機能的には期待どおりに機能しますが、そのパフォーマンスはまだ私が考えているほどではありません. アプリはシステム コールの同期に多くの時間を費やしているようです。そのため、いくつかのプロファイリングの後、最も適切な同期メカニズムを選択したかどうか疑問に思います。

アルゴリズムの重要な要件は、段階的に進行する必要があるため、各段階の最後にスレッドを同期する必要があることです。メインスレッドは作業を準備し (非常に低いオーバーヘッド)、それをスレッドに渡し、作業をさせ、すべてのスレッドが完了すると処理を進め、作業を再配置し (これも非常に低いオーバーヘッド)、サイクルを繰り返します。マシンはこのタスク専用であり、事前に割り当てられた項目のスレッドごとのプールを使用することでガベージ コレクションが最小限に抑えられ、スレッドの数を固定できます (着信要求などはなく、CPU コアごとに 1 つのスレッドのみ)。

V1 - ExecutorService

私の最初の実装では、8 つのワーカー スレッドを持つ ExecutorService を使用しました。プログラムは、作業を保持する 8 つのタスクを作成し、大まかに次のように作業させます。

これは機能的にはうまく機能し (本来あるべきことを行います)、実際、非常に大きな作業項目の場合、処理アルゴリズムが許容できる限り、8 つの CPU すべてに高い負荷がかかります (一部の作業項目は他の作業項目よりも速く終了し、その後アイドル状態になります)。 . ただし、作業項目が小さくなると (これは実際にはプログラムの制御下にはありません)、ユーザーの CPU 負荷は劇的に減少します。

凡例: - ブロック サイズ = ワークアイテムのサイズ (= 計算ステップ) - システム = OS X アクティビティ モニター (赤いバー) で示されるシステム負荷 - ユーザー = OS X アクティビティ モニター (緑のバー) で示されるユーザー負荷- サイクル/秒 = メインの while ループの繰り返し、多いほど良い

ここで主に懸念されるのは、システムで費やされる時間の割合が高いことです。これは、スレッド同期呼び出しによって引き起こされているようです。予想どおり、小さい作業項目の場合、ExecutorService.invokeAll() は、各スレッドで実行される作業の量に対して、スレッドを同期するためにより多くの労力を必要とします。しかし、ExecutorService は、このユース ケースで必要とされるよりも一般的であるため (コアよりも多くのタスクがある場合、スレッドのタスクをキューに入れることができます)、より無駄のない同期構造が存在する可能性があります。

V2 - CyclicBarrier

次の実装では、大まかに次のように、CyclicBarrier を使用して、作業を受け取る前と完了した後にスレッドを同期させました。

繰り返しますが、これは機能的にはうまく機能し (本来あるべきことを行います)、非常に大きな作業項目の場合、以前と同様に 8 つの CPU すべてに高い負荷がかかります。ただし、作業項目が小さくなると、負荷は依然として劇的に縮小します。

大規模な作業項目の場合、同期は無視でき、パフォーマンスは V1 と同じです。しかし予想外に、(高度に専門化された) CyclicBarrier の結果は、(一般的な) ExecutorService の結果よりもはるかに悪いように見えます: スループット (サイクル/秒) は V1 の約 1/4 にすぎません。これは CyclicBarrier の宣伝されている理想的な使用例のように見えますが、一般的な ExecutorService よりもパフォーマンスがはるかに悪いというのが暫定的な結論です。

V3 - 待機/通知 + CyclicBarrier

最初の循環バリア await() を単純な待機/通知メカニズムに置き換えてみる価値があるように思われました。

繰り返しますが、これは機能的にうまく機能します (本来あるべきことを行います)。

小さな作業項目のスループットは、ExecutorService よりもはるかに劣りますが、CyclicBarrier の約 2 倍です。CyclicBarrier を 1 つ削除すると、ギャップの半分が削除されます。

V4 - 待機/通知の代わりにビジー待機

このアプリはシステム上で実行されている主要なアプリであり、コアが作業項目でビジーでない場合はとにかくアイドル状態であるため、CPU を不必要に回転させても、各スレッドで作業項目をビジー状態で待機してみませんか。ワーカー スレッド コードは次のように変更されます。

また、機能的にもうまく機能します(本来あるべきことを行います)。

小さな作業項目の場合、これにより、CyclicBarrier + 待機/通知バリアントよりもスループットがさらに 10% 向上しますが、これは重要ではありません。ただし、ExecutorService を使用した場合でも、V1 よりもはるかにスループットが低くなります。

V5 - ?

では、そのような (おそらく珍しいことではない) 問題に最適な同期メカニズムは何でしょうか? ExecutorService を完全に置き換える独自の同期メカニズムを作成するのにうんざりしています (それがあまりにも一般的であり、より効率的にするためにまだ取り出すことができるものが必要であると仮定します)。それは私の専門分野ではなく、不確実な利益のためにデバッグに多くの時間を費やすことになるのではないかと心配しています(待機/通知およびビジー待機バリアントが正しいかどうかさえわからないため)。

アドバイスをいただければ幸いです。

0 投票する
14 に答える
96930 参照

java - Javaの同時実行性:カウントダウンラッチとサイクリックバリア

java.util.concurrent APIを読んでいたところ、

  • CountDownLatch:他のスレッドで実行されている一連の操作が完了するまで、1つ以上のスレッドが待機できるようにする同期支援。
  • CyclicBarrier:一連のスレッドが互いに共通のバリアポイントに到達するのをすべて待機できるようにする同期支援。

私には両方とも同じように見えますが、それ以上のものがあると確信しています。

たとえば、CoundownLatch, the countdown value could not be reset, that can happen in the case of CyclicBarrier

2つの間に他の違いはありますか?誰かがカウントダウンの値をリセットしたい場所はどこですか
use cases

0 投票する
1 に答える
364 参照

java - CyclicBarrier に関係なく、1 つのスレッドの停止が早すぎる

次のコードが下品に見えるかもしれないという事実を認識していますが、私はこれらのことに慣れておらず、機能させるためにすべてを試しました..

問題: CyclicBarrier を (間違った方法で使用している可能性があります) 使用しているにもかかわらず、1 つ (常に同じように見えます) スレッドがすぐに停止し、ベクターを出力して、「着信接続」メッセージの 11 のうち 1 つが欠落したままになります. ループの最後の繰り返しで何かひどく間違っている可能性がありますが、正確に何が何かを見つけることができないようです..今、プログラムは最後の接続を処理するのを待ってループします。


明確にするために、使用されるファイルの形式を次に示します。 構成には、スレッドであるクライアントが使用するホスト名とポートが含まれており、入力ファイルの行は、「このクライアントがそのクライアントにメッセージを送信する」または「このクライアントが論理クロックを一定の値だけインクリメントする」ことを意味します。

1 M 2 (M はメッセージの送信を意味します)
2 M 3
3 M 4
2 L 7 (L は増分クロックを意味します)
2 M 1
...
127.0.0.1 9000
127.0.0.1 9001
127.0.0.1 9002
127.0.0.1 9003
...

0 投票する
2 に答える
210 参照

java - new CyclicBarrier(n) の "n" の数は?

最近CyclicBarrierを学びましたが、ここで質問です:

コード:

コードについてですが、メイン メソッドで await() を呼び出したことがないのに、(threadsCount) ではなく (threadsCount + 1) で CyclicBarrier を初期化する必要があるのはなぜでしょうか。

0 投票する
1 に答える
191 参照

java - CyclicBarrier.await()関数がNullポインター例外を生成する理由は何でしょうか。

CyclicBarrierクラスawait()を使用して、さまざまなドキュメントを同時に処理するさまざまなスレッドを同期しています。ただし、この関数は、ドキュメントのほとんどの入力でNullポインタ例外を返すようです。この例外を回避するために誰かが私を助けてくれますか?

0 投票する
2 に答える
421 参照

java - Java - スレッドを正常に終了する

計算を実行するスレッドがたくさんあります。を使用して「同期」されCyclicBarrierます。いずれかのスレッドのrun()メソッドが終了したら、次回バリアを呼び出したら、他のすべてのスレッドも終了するようにします。await()

これまでのところ、私が試したことはすべて、await()呼び出しでハングするか、バリアが壊れてしまいます。任意のヒント?

編集: (基本的な) コードは次のとおりです。

0 投票する
9 に答える
16243 参照

java - リセット可能なカウントダウンラッチ

と直接同等であるCountDownLatchが、リセット可能なものが必要です (スレッドセーフのままです!)。このような状況では機能しないため、従来の同期構造は使用できません (複雑なロックの問題)。現在、私は多くのCountDownLatchオブジェクトを作成しており、それぞれが前のものを置き換えています。これはGCの若い世代で行われていると思います(オブジェクトの数が非常に多いため)。以下のラッチを使用するコードを見ることができます (これjava.netは ns-3 ネットワーク シミュレータ インターフェイスのモックの一部です)。

CyclicBarrier(JDK5+) またはPhaser(JDK7)を試すことも考えられます。

私はコードをテストして、この問題の解決策を見つけた人に連絡を取ることができます。実行中のシステムにコードを挿入して何が起こるかを確認できるのは私だけだからです :)

乾杯、
クリス

0 投票する
3 に答える
2206 参照

c# - .NET 3.5 で .NET 4 機能から Barrier クラスを実装する方法

何らかの理由で、.NET 3.5 に固執する必要があり、.NET 4 の Barrier クラスの機能が必要です。いくつかの作業を行うスレッドがたくさんあり、すべてが完了するまで相互に待機する必要があります。すべてが終わったら、同じように何度も何度もやってもらいたいと思います。C# 4.0 の Barrier と C# 3.0 の WaitHandle の違いというスレッドに励まされていますか? AutoResetEvent クラスと WaitHandle クラスを使用して Barrier 機能を実装することにしました。私のコードで問題が発生しましたが:

私が受け取る出力は次のとおりです。

「バリア」のスレッド 0 は 7564 の間スリープします 「バリア」のスレッド 1 は 5123 の間スリープします 「バリア」のスレッド 2 は 4237 の間スリープします 「バリア」のスレッド 2 は時間 4237 で「バリア」のスレッド 1時間 5123 で 'バリア' のスレッド 0 時間 7564 'バリア' でのスレッド 0 は 8641 時間スリープします 'バリア' でのスレッド 0 時間 8641

以上です。最後の行の後、それ以上の出力はなく、アプリは終了しません。ある種の行き詰まりがあるようです。ただし、問題が見つかりません。どんな助けでも大歓迎です。

ありがとう!

0 投票する
1 に答える
1354 参照

countdownlatch - CyclicBarrier と CountDownLatch?

CyclicBarrier と CountDownLatch の違いは何ですか? どちらも同じように見えるので、微妙な違いがあると思います。

私が間違っている場合はお知らせください。また、同じことを説明してください。