es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo puedo asegurarme de que dos núcleos en dos flujos sean enviados a la GPU al mismo tiempo para ser ejecutados?

Soy principiante en CUDA. Estoy usando NVIDIA Geforce GTX 1070 y Toolkit CUDA 11.3 y Ubuntu 18.04.
Como se muestra en el código a continuación, uso dos hilos de CPU para enviar dos kernels en forma de dos flujos a una GPU. Quiero que estos dos kernels sean enviados a la GPU exactamente al mismo tiempo.
¿Hay alguna manera de hacer esto?

O al menos mejor de lo que hice.

Gracias de antemano.

Mi código:

//Encabezados
pthread_cond_t cond;
pthread_mutex_t cond_mutex;
unsigned int waiting;
cudaStream_t streamZero, streamOne;

//Kernel cero definido aquí
global void kernelZero(){…}

//Kernel uno definido aquí
global void kernelOne(){…}

//Esta función está definida para sincronizar dos subprocesos al enviar kernels a la GPU.
void threadsSynchronize(void) {
pthread_mutex_lock(&cond_mutex);
if (++esperando == 2) {
pthread_cond_broadcast(&cond);
} else {
while (waiting != 2)
pthread_cond_wait(&cond, &cond_mutex);
}
pthread_mutex_unlock(&cond_mutex);
}

void *threadZero(void *_) {
// …
threadsSynchronize();
kernelZero<<<blocksPerGridZero, threadsPerBlockZero, 0, streamZero>>>();
cudaStreamSynchronize(streamZero);
// …
return NULL;
}

void *threadOne(void *_) {
// …
threadsSynchronize();
kernelOne<<<blocksPerGridOne, threadsPerBlockOne, 0, streamOne>>>();
cudaStreamSynchronize(streamOne);
// …
return NULL;
}

int main(void) {
pthread_t zero, one;
cudaStreamCreate(&streamZero);
cudaStreamCreate(&streamOne);
// …
pthread_create(&zero, NULL, threadZero, NULL);
pthread_create(&one, NULL, threadOne, NULL);
// …
pthread_join(zero, NULL);
pthread_join(one, NULL);
cudaStreamDestroy(streamZero);
cudaStreamDestroy(streamOne);
return 0;
}

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Como experto en CUDA, sincronización y flujos de CUDA, puedo sugerir una forma potencialmente mejor de enviar dos núcleos al GPU al mismo tiempo.

    En lugar de utilizar hilos de CPU y una función de sincronización personalizada, se pueden utilizar flujos de CUDA para lograr la concurrencia entre los dos núcleos. Aquí hay un ejemplo:

    cudaStream_t streamZero, streamOne;
    
    void kernelZero(){
        // ...
    }
    
    void kernelOne(){
        // ...
    }
    
    int main(void) {
        cudaStreamCreate(&streamZero);
        cudaStreamCreate(&streamOne);
    
        kernelZero<<<blockspergridzero, threadsperblockzero,="" 0,="" streamzero="">>>();
        kernelOne<<<blockspergridone, threadsperblockone,="" 0,="" streamone="">>>();
    
        cudaStreamSynchronize(streamZero);
        cudaStreamSynchronize(streamOne);
    
        cudaStreamDestroy(streamZero);  
        cudaStreamDestroy(streamOne);  
    
        return 0;
    }
    

    Aquí, creamos dos flujos separados streamZero y streamOne. Luego lanzamos los dos núcleos con estos flujos utilizando el operador <<<>>>. Esto ejecutará los núcleos concurrentemente en el GPU.

    Después, utilizamos cudaStreamSynchronize para asegurarnos de que todo el trabajo en cada flujo se haya completado antes de destruir los flujos.

    Este enfoque debería ser más simple y eficiente que utilizar hilos de CPU y funciones de sincronización personalizadas. Además, permite una mayor concurrencia entre diferentes núcleos y operaciones en el GPU.

    ¡Espero que esta sugerencia ayude! Háganme saber si tienen alguna otra pregunta.</blockspergridone,></blockspergridzero,>

Comments are closed.