Если у меня есть две программы, которые связаны между собой, возможно ли, чтобы у меня было одно ядро, работающее на 1 SM, другое ядро, работающее на других SM (или SM) в одно и то же время. Также мне нужно, чтобы они могли общаться друг с другом через глобальную память. Является ли это возможным? Могу ли я использовать поток cuda для достижения этого?
Это теоретически возможно, да.
Я думаю, что он подвержен неприятностям, потому что, в отличие от глобальной синхронизации в ядре, это зависит от того, как оба ядра смогут достичь своих соответствующих точек синхронизации. Обычно это подразумевает очень маленькие ядра, где вы можете гарантировать, что независимо от порядка запуска блоков вы попадете в точку синхронизации.
Но возможен простой возможный случай:
#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, вам может потребоваться расследование с использованием динамического параллелизма (запуск одного ядра из другого).