2

このコードサンプルが与えられた場合、演習はタスクを使用してコードをOpenMPと並列化することです。アイテムのセットで、良いものを数えたいです。

int count_good (item_t* item)
{
    int n = 0;
    while (item) {
       if (is_good(item))
          n++;
       item = item->next;
    }
    return n;
}

これは正確には宿題ではありません。試験の準備用です。私の考えは次のとおりです。

int count_good (item_t* item)
{
    int n = 0;
    while (item) {
       #pragma omp task
       {
       if (is_good(item))
          n++;
       }
       item = item->next;
    }
    #pragma omp taskwait
    return n;
}
...

int main ()
{
...
#pragma omp parallel
{
#pragma omp single
    count_good(some_times);
}
}

問題は、nこれがシングルスレッドのプライベート変数であるということですが、同時に異なるタスクによって増加する可能性があります。これにより競合状態が発生する可能性がありますか?で回避できます#pragma omp criticalか?

4

2 に答える 2

2

reduction「良い」アイテムをカウントするために使用できます。次のコードはあなたのために仕事をします。削減のためにこれを読み、リンクされたリストをトラバースするためにこれを読むことをお勧めします

int nCount = 0;
#pragma omp parallel reduction(+ : nCount)
{       
    for(struct item_t *listWalk = some_items; listWalk != NULL; 
      listWalk = listWalk->next)
    {
        #pragma omp single nowait
        {
            if( isGood(listWalk) ){
            nCount += 1;
            }
        }           
    }
}
于 2013-02-19T09:55:38.433 に答える
1

nとして明示的に宣言する必要がsharedあります。そうしないと、デフォルトで宣言されます(これは、囲んでいるコンテキストにfirstprivate暗黙的に含まれているため)。private次に、のアトミック増分を確保するために、構成nを適用する必要がありますatomic update。最終的に、コードは次のようになります。

int count_good (item_t* item)
{
    int n = 0;
    while (item) {
       #pragma omp task shared(n)
       {
       if (is_good(item))
          #pragma omp atomic update
          n++;
       }
       item = item->next;
    }
    #pragma omp taskwait
    return n;
}

コンストラクトは、critical少なくともx86では、アトミック増分よりもはるかに高いオーバーヘッドがあります。

于 2013-02-19T12:21:40.527 に答える