如果我有2个相关的程序,我可以在1个SM上运行一个内核,同时在其他SM(或SM)上运行另一个内核。我还需要它们能够进行通信通过全球记忆彼此相处。可能吗?我可以使用cuda流来实现这个目标吗?
答案 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
如果从内核启动中删除stream1
和stream2
标识符,程序将挂起(因为内核都启动到同一个流中,因此序列化。)
同样,我认为这不是一个好的设计,但在某些情况下它是可能的。
如果您使用的是cc3.5或更高版本的GPU,则可能需要使用dynamic parallelism进行调查(从另一个启动一个内核)。