2

私はこのようなコードを持っています:

#pragma omp parallel
{
    #pragma omp single
    {
        int x;
        #pragma omp task depend(inout:x)
        {
            for (int i = 1; i < 16; i++)
            {
                 #pragma omp task
                 DoComputationOnPartition(i);
            }
            #pragma omp taskwait
        }
        for (int i = 1; i < 16; i++)
        {
          #pragma omp task depend(in:x)
          {
             OperateOnPartition(i);
          }
        }
        #pragma omp task depend(inout:x)
        {
           for (int i =1; i < 16; i++) x++;
        }

        for (int i = 1; i < 16; i++)
        {
          #pragma omp task depend(in:x)
          {
             OperateOnPartition(i);
          }
        }
        #pragma omp taskwait
    }
}

そして、私が見つけたのは、マスタースレッドが最初のタスク内にネストされた DoComputationOnPartition のタスクを実行できないことです。誰かがそれを説明できますか?それはうまくいくはずですよね?#pragma omp taskwait はスケジューリング ポイントであるため、チームのどのスレッドでもタスクを取得できる必要があります。マスター スレッドは最後の taskwait に到達し、ネストされたタスクを取得できるはずです。それらには、それを可能にするのに十分な長さがあります。

ありがとう。

4

2 に答える 2

0

OpenMP 4.0 仕様に従って:

バインドタスクグループ領域は、現在のタスク領域にバインドされます。taskgroup 領域のバインド スレッド セットは、現在のチームです。

説明スレッドが taskgroup 構造を検出すると、領域の実行を開始します。タスクグループ領域の最後に暗黙のタスク スケジューリング ポイントがあります。現在のタスクは、タスク グループ領域で生成されたすべての子タスクとそのすべての子孫タスクの実行が完了するまで、タスク スケジューリング ポイントで中断されます。

つまり、タスクをタスクグループ内に配置することを意味します。まぁ、いいよ。ただし、タスク待機と同じように、スケジューリング ポイントも意味します。libgomp に問題がある場合、それはそのランタイム固有の問題であり、API としての OpenMP ではありません。ICC や OmpS などの他のランタイムには、このような動作の問題はありません:-S

Taskgroup は、タスクのすべての階層を待ちたい場合にのみ意味がありますが (私が見ているように)、そうではありません。

私はあなたがこれを意味すると思いますよね?:

 #pragma omp task depend(inout:x)
 {
        #pragma omp taskgroup
        {
            for (int i = 1; i < 16; i++)
            {
                 #pragma omp task
                 DoComputationOnPartition(i);
            }
        }
  }

元のコードでは、最初の taskwait が別のコンテキスト内にネストされているため、その taskwait で待機しているタスクのグループはごくわずかです。

于 2015-11-17T13:58:05.760 に答える