多くの再帰アルゴリズムに依存するプロジェクトの一部を並列化しようとしています。
それらのほとんどは、バイナリ ツリーの作成またはトラバーサルと処理の何らかの形式です。
RedHat で GCC v. 4.1.2 を使用し、Windows で VC++ コンパイラを使用することに行き詰まっています (どちらも、便利な構造を持つ OpenMP 3.0 をサポートしていませんtask
)。ネストされた並列セクションと、法外な数のスレッドを防ぐためのスロットリングで仕事を成し遂げるように見えるこの質問を見つけました。
私の質問:このアプローチを回避する方法はありますか? 一部の関数はタイムステップごとに呼び出され、スレッド チームの作成と破棄を繰り返すオーバーヘッドは受け入れられません。
リンクされた質問に沿って、私が使用してきた再帰関数の基本構造を次に示します。
extern int threads;
omp_set_nested(1); omp_set_num_threads(2);
void cell::updateRecursive() {
// do stuff for cell for this timestep
#pragma omp flush(threads)
if (threads>=omp_get_num_procs()) {
child0->updateRecursive(); child1->updateRecursive(); // no new threads
} else {
#pragma omp atomic
threads++;
#pragma omp flush(threads)
#pragma omp parallel sections nowait
{
#pragma omp seciton
child0->updateRecursive();
#pragma omp section
child1->updateRecursive();
}
#pragma omp atomic
threads--;
}
}
この関数がそれほど頻繁に呼び出されない場合は、これで十分です。ツリーをトラバースしながらスレッドを作成するのではなく、既存のスレッドのチームを使用して作業を実行できる再帰の方法が必要です。
これは、なしでまったく可能でしょうtask
か? 単純に を使用して実験しましたsections
が、既存のスレッドのチームを使用するためにネストすることはできないようです。