2

最近、CUDA コードを OpenMP と結合しようとしましたが、いくつかの問題が発生します。私のCUDA-OpenMPコードは次のように書かれています

    int main (void)
    {
       cudaGetDeviceCount(&gpuNum);

       //declare variables
       float *data_h; *data_d[gpuNum];
       data_h = (float*)malloc(Mem);
       ....
       ....
       omp_set_num_threads(gpuNum); 
       #pragma omp parallel
       {
         int cpuid = omp_get_thread_num();
         cudaSetDevice(cpuid);

         cudaMalloc((void**)&data_d[cpuid], Mem );

         cudaMemcpy( data_d[cpuid], data_h, Mem, cudaMemcpyHostToDevice);
         kernel<<< gpu_block, gpu_thread >>>();
         cudaMemcpy( data_h, data_d[cpuid], Mem, cudaMemcpyDeviceToHost);
       }
       printf("end of parallel\n");
       //post process
     }

問題は、このコードを実行するとすべてがうまくいく場合があることですが、場合によっては停止し、「並列の終わり」の文が出力されないことがあります。この状況はランダムに発生しますが、その理由を誰か教えていただけますか?

4

2 に答える 2

2

いくつかの失敗の可能性を提供したい:

並列領域で、最初の 2 行が実行されると、アクティブなスレッドが別のスレッドに切り替えられることを想像してください。

#pragma omp parallel{
  int cpuid = omp_get_thread_num();
  cudaSetDevice(cpuid);
  ...
}

次に、別のスレッドが set device 関数を呼び出し、選択されたデバイスが変更されます。

memcopy 操作がブロックしている間、カーネル呼び出しはブロックされていません。そのため、カーネル呼び出しの後にスレッドが切り替えられると、1 つのカーネル呼び出しが完了していない間に別のカーネル呼び出しが発行されます。並行カーネルを実行するには、「ストリーム」を使用する必要があります。を見てみましょう

ストリームごとに複数のカーネルを使用した CUDA 同時カーネル実行

于 2012-09-17T19:45:35.937 に答える
0

最高のパフォーマンスを達成したい場合は、OpenMP を使用して CUDA を実行しないことをお勧めします。私の経験から、OpenMP によるスレッドの作成はコストがかからず、時間がかかることを知っています。スレッドの作成中に、多くのデバイスでより多くの GPU カーネルを実行できます。

@phoad で述べたように、データセットが独立している場合はストリームを使用できます。ウェブ上で多くの例を見つけることができます。

もう 1 つの可能性は、カーネルを再設計することです。1 つのカーネルが同じ作業を行い、結果として配列を返すことができます。

于 2012-09-18T12:15:40.083 に答える