0
----------------a.c---------------------
variable *XX;
func1(){
  for(...){
    for(i = 0; i < 4; i++)
       cutStartThread(func2,args)
  } 
}
---------------b.cu-------------------
func2(args){
  cudaSetDevice(i);
  xx = cudaMalloc();
  mykernel<<<...>>>(xx);
}
--------------------------------------

最近、プログラムに複数の GPU デバイスを使用したいと考えています。私のノードには 4 枚の Tesla C2075 カードがあります。4 つのスレッドを使用して 4 つの GPU を管理します。さらに、各スレッドのカーネルは数回起動されます。上記のような単純な擬似コード。2 つの質問があります。

  1. 変数XXは非常に長い文字列で、カーネルでのみ読み取られます。の複数回の起動中にそれを保持したいmykernel。が最初に起動されたときだけに cudaMallocポインタを呼び出して渡すことはできますか? または、修飾子を使用する必要がありますか?mykernelmykernel__device__

  2. XXは 4 つのスレッドで使用されるため、 file でグローバル変数として宣言しますa.c。の倍数cudaMallocXX正しいですか、または次のような配列を使用する必要がありますvariable *xx[4]か?

4

1 に答える 1

1
  1. 単一のデバイスで実行されているカーネルで使用するには、cudaMalloc一度呼び出して文字列を保持する変数XXを作成し、cudaMalloc によって作成されたポインター (つまりXX) を必要なカーネルに渡すことができます。

    #define xx_length 20
    char *XX;
    cudaMalloc((void **)&XX, xx_length * sizeof(char));
    ...
    kernel1<<<...>>>(XX, ...);
    ...
    kernel2<<<...>>>(XX, ...);
    etc.
    
  2. 各スレッドが異なるデバイスへのアクセスに使用されていると想定して、スレッドごとに個別の XX 変数を作成します。これをどの程度正確に行うかは、XX の範囲によって異なります。しかし、次の配列:

    char *XX[num_devices]; 
    

グローバルスコープでは、問題ないはずです。

CUDA OpenMP サンプルは、複数のスレッドを使用して複数の GPU を管理する方法の例として興味深い場合があります。

于 2013-03-23T16:36:13.757 に答える