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 设备。我的节点上有四张 Tesla C2075 卡。我使用四个线程来管理四个 GPU。更重要的是,每个线程中的内核都会被启动多次。一个简单的伪代码如上。我有两个问题:

  1. 变量XX是一个很长的字符串,在内核中是只读的。我想在mykernel. 是否可以仅在 首次启动时调用cudaMalloc并将指针传递给?或者我应该使用限定符?mykernelmykernel__device__

  2. XX在四个线程中使用,因此我将其声明为 file 中的全局变量a.ccudaMalloc是正确的倍数XX还是应该使用数组,例如variable *xx[4]

4

1 回答 1

1
  1. 对于在单个设备上运行的内核的使用,您可以调用cudaMalloc一次来创建保存字符串的变量XX,然后将 cudaMalloc (ie 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]; 
    

在全球范围内,应该没问题。

作为如何使用多线程管理多个 GPU 的示例,CUDA OpenMP 示例可能很有趣。

于 2013-03-23T16:36:13.757 回答