1

ツリーを処理していますが、GPAR を使用して高速化したいと考えています。単純なことには使用しましたが、より複雑なオプションについては詳しく説明していません。

ツリーのさまざまなブランチを独自のスレッドで処理しているとします。

ノードに名前があるとしましょう。そのノードに初めてヒットしたときに、それを処理し (データベースへの書き込みなどを含む)、キャッシュに追加します (ここでは単純なマップのみ)。

ツリーの他の場所で同じノード (同じ名前のノードなど) にヒットする可能性のある他のスレッドがキャッシュをチェックできるようにします。すでにキャッシュにある場合は、それを取得して先に進むことができます。別のスレッドがそのノードの処理に初めて取り組んでいる場合、ブランチ内のそのノードにある他のスレッドがツリーを下る前に待機する必要があります (そのノードが既に処理されていることに依存する他のものに)。

ノードはデータベースからプルされるため、各ブランチで同じオブジェクトではありません。同期されたメソッドは機能しないと思います。

もちろん、関係のない他のノードも処理し続けたいと思います。

例えば:

  • スレッド 1 は ABCD を処理しています
  • スレッド 2 は EBFG を処理しています
  • スレッド 3 は WXY を処理しています
  • スレッド 4 は LMNOPQRSBJ を処理しています

スレッド 1 が最初にノード B に到達するとします。キャッシュにないことがわかったので、処理を開始します。

スレッド 2 は、ノード B がキャッシュにないことを確認しますが、作業中です。そのため、スレッド 1 がノード B の処理を​​完了するまで、ノード F に進むのを待ちます。

スレッド 3 はノード B を気にしないため、クランキングを続けます。

スレッド 4 は、スレッド 1 がノード B の処理を​​終了し、キャッシュ内でノード B を見つけた後に発生するため、キャッシュからそれをプルして、ノード J に進みます。

この状況に GPAR を最適に適用する方法の提案を探しています。

ありがとう!

4

1 に答える 1

2

私が最初に考えたのは、ノード名をキーとし、DataflowVariables を値とする共有 ConcurrentHashmap を使用することです。

スレッドは putIfAbsent(nodename, new DataflowVariable()) を使用して、処理されたノードのデータの promise をアトミックに挿入します。操作が成功した場合、スレッドはノードの処理を開始し、最終的に結果を DataflowVariable にバインドします。

putIfAbsent() が失敗した場合、他のスレッドがすでに同じ名前のノードの処理を開始しています。その場合、現在のスレッドは、ノード名に関連付けられた DataflowVarieble を取得し、get() または whenBound() を呼び出して、結果が利用可能になるのを待つだけです。

于 2012-11-09T04:55:39.710 に答える