CUDA define alguns parâmetros e não tenho certeza de como o CUDA se comporta, se tenho que respeitá-los ou se não os respeito ele funciona, mas talvez não com o melhor desempenho.
Ao olhar, cudaGetDeviceProperties
posso ver alguns parâmetros (retirados do site da NVidia: https://docs.nvidia.com/cuda/cuda-runtime-api/group__CUDART__DEVICE.html#group__CUDART__DEVICE_1g1bf9d625a931d657e08db2b4391170f0 :
concurrentKernels
: O dispositivo pode executar vários kernels simultaneamente
Isso é apenas uma bandeira ou há algum impacto? Acho que kernels simultâneos só fazem sentido se streams forem usados, certo? (veja também asyncEngineCount).
asyncEngineCount
: Número de motores assíncronos
Este é o número de kernels que podem ser executados em paralelo, conforme indicado acima. Também aqui acho que isso só funciona quando são usados streams, certo?
Isso me leva a uma questão mais geral sobre streams . Quantos fluxos podem ser usados ou alocados? Por exemplo, se asyncEngineCount
for 3, faz sentido ter mais de 3 fluxos? Se isso não for verdade, faz sentido alocar mais fluxos do que o arquivo asyncEngineCount
.
O que aconteceria se eu alocasse mais streams do que asyncEngineCount e permitisse que vários kernels fossem executados simultaneamente? Vamos supor que eu aloque 10 streams e execute 10 kernels simultaneamente, mas o asyncEngineCount tem apenas 3. O CUDA executaria apenas 3 kernels por vez e os outros seriam bloqueados até que um stream estivesse livre?
Eu sempre interpretei um fluxo como um objeto de sincronização simples que não é sinalizado quando um método assíncrono CUDA é invocado, para que outros métodos esperem até que o método saia e o fluxo seja definido como sinalizado, mas isso parece uma explicação simplificada da minha parte, talvez ?
Não consegui encontrar uma boa explicação sobre execução e fluxos assíncronos, talvez com uma visão mais profunda. Os documentos CUDA não parecem explicar detalhes. Talvez haja uma boa explicação na web ou em um livro?
É uma bandeira, um indicador de capacidade. Acho que basicamente todas as GPUs CUDA são capazes de executar kernels simultâneos. Eu ficaria muito surpreso se alguém encontrasse uma GPU CUDA que não tivesse essa capacidade.
Sim, para organizar qualquer tipo de simultaneidade em CUDA (duas ou mais coisas acontecendo ao mesmo tempo) geralmente é necessário fazer uso adequado de streams. Existem algumas pequenas exceções a isso, como a simultaneidade da execução do código do host e da execução do código do dispositivo.
Não não é. Um mecanismo assíncrono em CUDA pode ser considerado um mecanismo DMA e é necessário/usado sempre que você emite uma solicitação de transferência de dados assíncrona (por exemplo, )
cudaMemcpyAsync
que tem a capacidade real de ser executada de forma assíncrona. Para que a transferência aconteça de forma assíncrona, é utilizado um mecanismo de hardware, e esse mecanismo é chamado de mecanismo assíncrono. Os mecanismos assíncronos não têm uso ou influência em relação à atividade do kernel, exceto que o uso de um mecanismo assíncrono permitiria, por exemplo, que uma atividade de transferência de dados acontecesse ao mesmo tempo que um kernel está em execução, sujeito a vários requisitos e capacidade do dispositivo.Não há um limite máximo especificado para o número de fluxos que podem ser criados. Já vi códigos projetados corretamente que usam mais de 40 fluxos. Streams não têm conexão direta com o
asyncEngineCount
. Se você criar e usar mais fluxos do que a quantidade de conexões de dispositivos , os fluxos serão distribuídos ("alias") pelas conexões de dispositivos, mas as conexões de dispositivos também não têm nada explícito a ver com mecanismos assíncronos.Nada incomum aconteceria. Não há conexão entre
asyncEngineCount
fluxos e nem o número de kernels que você pode executar simultaneamente. A execução simultânea do kernel depende de fatores e recursos que não têm conexão com oasyncEngineCount
, e você certamente pode demonstrar mais do queasyncEngineCount
kernels rodando simultaneamente, e da última vez que verifiquei, o código de exemplo concurrentKernels faz isso. Há um limite superior/hardware (consulte a tabela 18) para o número de kernels simultâneos, mas não tem relação com mecanismos assíncronos.Para aprendizado geral de CUDA, geralmente recomendo esta série de treinamento on-line e a seção sobre "Simultaneidade CUDA" contém informações relevantes para este tópico. O guia de programação também possui uma seção estendida sobre Execução Simultânea Assíncrona em CUDA.