2

OpenMPparallel_forを使用する Intel TBB ループの同等の代替品を考え出そうとしています。tbb::blocked_rangeオンラインで調べてみると、他の人が似たようなことをしているという言及を見つけることができただけです。Open Cascade プロジェクトに提出されたパッチ。TBB ループはそのように見えます (ただし、tbb::blocked_range は使用しませんでした):

tbb::parallel_for_each (aFaces.begin(), aFaces.end(), *this);

OpenMP に相当するものは次のとおりです。

int i, n = aFaces.size();
#pragma omp parallel for private(i)
for (i = 0; i < n; ++i)
    Process (aFaces[i]);

置き換えようとしている TBB ループは次のとおりです。

tbb::parallel_for( tbb::blocked_range<size_t>( 0, targetList.size() ), DoStuff( targetList, data, vec, ptr ) );

クラスを使用DoStuffして作業を実行します。

class DoStuff
{
private:
    List& targetList;
    Data* data;
    vector<things>& vec;
    Worker* ptr;

public:
    DoIdentifyTargets( List& pass_targetList, 
                       Data* pass_data, 
                       vector<things>& pass_vec, 
                       Worker* pass_worker) 
        : targetList(pass_targetList), data(pass_data), vecs(pass_vec), ptr(pass_worker)
    {
    }

    void operator() ( const tbb::blocked_range<size_t> range ) const
    {
        for ( size_t idx = range.begin(); idx != range.end(); ++idx )
        {
            ptr->PerformWork(&targetList[idx], data->getData(), &Vec);
        }
    }
};

この参照に基づく私の理解では、TBB はブロックされた範囲をより小さなサブセットに分割し、各スレッドにループする範囲の 1 つを与えるということです。DoStuff各スレッドは、多数の参照とポインタを持つ独自のクラスを取得するため、スレッドは基本的にこれらのリソースを共有しています。

OpenMP での同等の代替として私が思いついたものは次のとおりです。

int index = 0;
#pragma omp parallel for private(index)
for (index = 0; index < targetList.size(); ++index)
{
    ptr->PerformWork(&targetList[index], data->getData(), &Vec);
}

私の制御の及ばない状況のため (これは +5 台のコンピューターにまたがるはるかに大規模なシステムの 1 つのコンポーネントにすぎません)、デバッガーを使用してコードをステップ実行して、何が起こっているかを正確に確認することは... ありそうにありません。私はリモート デバッグに取り組んでいますが、あまり有望ではないようです。私が確かに知っているのは、上記の OpenMP コードが何らかの形で TBB とは異なることを行っており、各インデックスに対して PerformWork を呼び出した後に期待される結果が得られないということだけです。

上記の情報を踏まえて、OpenMP コードと TBB コードが機能的に同等ではない理由について何か考えがある人はいますか?

4

1 に答える 1

1

Ben と Rick のアドバイスに従って、omp プラグマを使用せずに次のループを (シリアルに) テストし、期待どおりの結果が得られました (非常にゆっくりと)。プラグマを再度追加すると、並列コードも期待どおりに動作します。問題は、ループの外側でインデックスをプライベートとして宣言するか、ループ内で numTargets をプライベートとして宣言することにあったようです。または両方。

    int numTargets = targetList.size();
    #pragma omp parallel for
    for (int index = 0; index < numTargets; ++index)
    {
        ptr->PerformWork(&targetList[index], data->getData(), &vec);
    }
于 2014-01-06T16:14:49.023 に答える