是否有可能同时在GPU上运行2个内核,并相互通信?

时间:2014-05-20 21:58:07

标签: c++ c cuda gpu

如果我有2个相关的程序,我可以在1个SM上运行一个内核,同时在其他SM(或SM)上运行另一个内核。我还需要它们能够进行通信通过全球记忆彼此相处。可能吗?我可以使用cuda流来实现这个目标吗?

1 个答案:

答案 0 :(得分:2)

理论上可行,是的。

我认为它很容易出现问题,因为与内核中的全局同步不同,它依赖于两个内核能够到达各自的同步点。这通常意味着非常小的内核,您可以保证无论块的启动顺序如何,您都将进入同步点。

但是一个简单的证据可能的案例如下:

#include <stdio.h>
#include <unistd.h>
__device__ volatile unsigned int sem = 0;
__global__ void kernel1(){

  while(sem < 1);
  printf("kernel1 received signal, sending return signal\n");
  sem = 2;
  __threadfence();
}

__global__ void kernel2(){

  printf("kernel2 sending signal\n");
  sem = 1;
  __threadfence();
  while(sem<2);
  printf("kernel2 received signal\n");
}


int main(){

  cudaStream_t stream1, stream2;
  cudaStreamCreate(&stream1);
  cudaStreamCreate(&stream2);
  printf("Launching kernel 1\n");
  kernel1<<<1,1,0,stream1>>>();
  sleep(2);
  printf("Launching kernel 2\n");
  kernel2<<<1,1,0,stream2>>>();
  cudaDeviceSynchronize();
  return 0;
}

这需要至少针对cc2.0设备进行编译。

运行时,它应该输出如下:

Launching kernel 1
Launching kernel 2
kernel2 sending signal
kernel1 received signal, sending return signal
kernel2 received signal

如果从内核启动中删除stream1stream2标识符,程序将挂起(因为内核都启动到同一个流中,因此序列化。)

同样,我认为这不是一个好的设计,但在某些情况下它是可能的。

如果您使用的是cc3.5或更高版本的GPU,则可能需要使用dynamic parallelism进行调查(从另一个启动一个内核)。