2012-08-14 12 views
7

Esta pregunta se relaciona con el uso de flujos de CUDA para ejecutar muchos núcleoscómo reducir CUDA latencia de sincronización/retrasar

En CUDA hay muchos comandos de sincronización cudaStreamSynchronize, CudaDeviceSynchronize, cudaThreadSynchronize, y también cudaStreamQuery para comprobar si las corrientes están vacías

Cuando utilicé el generador de perfiles noté que estos comandos de sincronización introducen un gran retraso en el programa. Me preguntaba si alguien sabe algún medio para reducir esta latencia aparte de, por supuesto, usando la menor cantidad de comandos de sincronización posible.

También hay algunas cifras para juzgar el método de sincronización más eficiente. eso es considerar 3 secuencias usadas en una aplicación y dos de ellas deben completarse para poder lanzar una cuarta secuencia si utilizo 2 cudaStreamSyncs o solo una cudaDeviceSync, ¿en qué incurrirá menos pérdida?

+1

cudaThreadSynchronize está en desuso. –

Respuesta

8

La principal diferencia entre los métodos de sincronización es "polling" y "blocking".

"Sondeo" es el mecanismo predeterminado para que el controlador espere la GPU: espera que la ubicación de la memoria de 32 bits alcance un cierto valor escrito por la GPU. Puede devolver la espera más rápido después de que se resuelva la espera, pero mientras espera, quema un núcleo de la CPU que mira esa ubicación de la memoria.

"Bloqueo" se puede solicitar llamando al cudaSetDeviceFlags() con cudaDeviceScheduleBlockingSync, o llamando al cudaEventCreate() con cudaEventBlockingSync. El bloqueo de espera hace que el controlador inserte un comando en el búfer de comandos de DMA que señala una interrupción cuando se han ejecutado todos los comandos anteriores en el búfer. El controlador puede asignar la interrupción a un evento de Windows o a un manejador de archivo de Linux, permitiendo que los comandos de sincronización esperen sin quemar constantemente la CPU, como lo hacen los métodos de sondeo predeterminados.

Las consultas son básicamente una verificación manual de esa ubicación de memoria de 32 bits utilizada para las esperas de sondeo; entonces en la mayoría de las situaciones, son muy baratos. Pero si ECC está habilitado, la consulta se sumergirá en el modo núcleo para verificar si hay algún error de ECC; y en Windows, todos los comandos pendientes se descargarán al controlador (que requiere un procesador de núcleo).

+0

Parece que la diferencia entre el sondeo y el bloqueo es que el sondeo consume tiempo de CPU y el bloqueo no. Sin embargo, no hay diferencia en el tiempo necesario para que ocurra la sincronización. En una situación donde la CPU no tiene que hacer ningún trabajo, se reduce a lo mismo. Es eso correcto ? – shadow

+0

Puede haber diferencias de tiempo, porque el manejo de interrupciones agrega latencia. Por lo tanto, a cambio de no quemar la CPU en la votación, pagas en forma de un tiempo más largo entre la espera que se resuelve y el hilo que se desbloquea como resultado. – ArchaeaSoftware

+0

¿Pero qué diferencia hay entre 'cudaDeviceScheduleBlockingSync' y' cudaDeviceScheduleYield'? 'cudaDeviceScheduleYield' tal como está escrito:" Indique a CUDA que ceda su hilo mientras espera los resultados del dispositivo. Esto puede aumentar la latencia al esperar el dispositivo, pero puede aumentar el rendimiento de los subprocesos de la CPU que funcionan en paralelo con el dispositivo ". - es decir, esperar el resultado ** sin grabar la CPU en el giro ** - es decir, "Bloquear". Y 'cudaDeviceScheduleBlockingSync' también - espera el resultado sin quemar la CPU en el giro. Pero que diferencia? – Alex