2

IntelTBBを使用してバイトニックソートを実装しています。parallel_invokeメソッドを使用すると、すべてうまくいきます。ただし、task_groupを(waitメソッドを呼び出さずに)使用すると、出力はソートされません。以下のようにtask_groupを使用すると、プログラムは終了しません。

void bitonic_merge(bool up, int array[],int size){
  if(size==1){
      return;
  }
  int m = greatestPowerOfTwoLessThan(size);
  bitonic_compare(up, array, size - m, m);
  g->run(Bitonic_Merge(up, array , m));
  g->run(Bitonic_Merge(up, &array[m],size - m));
  g->wait();
  return;    
}

誰かが何が悪いのかわかりますか?parallel_invokeとtask_groupの使用の違いは何ですか?また、そのような状況で使用するのに良いものは何ですか?parallel_invokeまたはtask_group?_ または、他の方法を使用する必要がありますか?

前もって感謝します

4

3 に答える 3

4

デッドロックのため、プログラムは終了しません。あなたのコードは非常に正しいですが、問題は、「g」が task_group へのグローバル ポインターであり、再帰的なタスク分解を行っていることであり、これはうまく混ざり合う組み合わせではありません。

デバッガーに侵入した場合、タスクが完了するのを待っている task_group::wait に多くのスレッドが表示されると思います。

スレッドとタスクの間で task_group を共有しており、それらはすべて互いに効果的に待機しているため、タスクは完了していません。

これを修正するには、bitonic_merge 関数内のスタックで task_group (またはstructured_task_group) を宣言します。すべての子タスクが完了すると、wait の呼び出しが完了し、デッドロックが回避されます。

私は、PPL の msdn フォーラムで同様の質問にパフォーマンスの傾斜を付けて回答したことに注意してください。また、task_group、structured_task_group、parallel_invoke、および parallel_for / parallel_for_each の構文とセマンティクスは、PPL と TBB の間で一貫していることを思い出してください。あなたやあなたのプラットフォームにとって意味のあるものを使用してください。

于 2011-04-20T07:13:39.253 に答える
0

ここでは、タスク グループを待機することが重要です。wait() がないと、関数は task_group::run() で行われた再帰的な「呼び出し」が完了する前に戻り、明らかにアルゴリズムを壊します。parallel_invoke は実際に適用可能であり、「呼び出された」関数が完了するのを自動的に待機するため、使いやすくなっています。(TBB 開発者として) 私が心配しているのは、指定されたプログラム スニペットが終了しない理由です。私が知る限り、うまくいくはずです。プログラムの完全なソースを提出していただけませんか (ここまたはTBB フォーラムのいずれかで?)

于 2011-03-25T21:43:25.653 に答える
0

サブ問題の数が一定の場合は、tbb::parallel_invoke を使用します。それ以外の場合は、再帰と task_group を使用してください。サブ問題の数が 2 であるため、parallel_invoke が適切で実装が簡単です。

詳細については、Intel TBB 設計パターンを参照してください。

于 2011-03-24T20:34:13.463 に答える