Можно ли одновременно запускать 2 ядра на графическом процессоре и общаться друг с другом?

0

Если у меня есть две программы, которые связаны между собой, возможно ли, чтобы у меня было одно ядро, работающее на 1 SM, другое ядро, работающее на других SM (или SM) в одно и то же время. Также мне нужно, чтобы они могли общаться друг с другом через глобальную память. Является ли это возможным? Могу ли я использовать поток cuda для достижения этого?

  • 1
    Даже если это возможно, это хорошая идея? Как правило, вы не хотите каких-либо условных ветвлений, спящих или блокирующих функций в ваших ядрах, которые вам обязательно потребуются, если вы хотите напрямую взаимодействовать между ядрами.
  • 0
    Основная причина в том, что я разработал какое-то ядро GPU, которое может понадобиться другой программе GPU для использования в полете
Показать ещё 6 комментариев
Теги:
cuda
gpu

1 ответ

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, вам может потребоваться расследование с использованием динамического параллелизма (запуск одного ядра из другого).

  • 2
    Любая из следующих ситуаций может зависнуть: она запускается в windows, и работа не передается в один и тот же командный буфер, она запускается на небольшом графическом процессоре (K1), если первое ядро имеет достаточно перекосов для насыщения SM ( это не относится к примеру), если первое ядро имеет достаточные перекосы для насыщения планировщика перекосов, если два ядра имеют разную конфигурацию запуска SM (конфигурация shared / L1 или конфигурация общего банка kepler), а первое запускает деформации NumSM.
  • 0
    Спасибо за ответ и комментарий. На самом деле мое первое ядро будет занимать весь SM. Будет ли это работать, если это так? Я бы хотел, чтобы второе ядро работало на другом СМ
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню