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.

Uso óptimo de los recursos de la GPU en caso de múltiples tareas interdependientes.

En mi caso de uso, la memoria global de la GPU tiene muchos fragmentos de datos. Preferiblemente, el número de estos podría cambiar, pero también está bien asumir que el número y los tamaños de estos fragmentos de datos son constantes. Ahora, hay un conjunto de funciones que toman como entrada algunos de los fragmentos de datos y modifican algunos de ellos. Algunas de estas funciones solo deben comenzar a procesar si otras ya han completado. En otras palabras, estas funciones podrían representarse en forma de gráfico con las funciones como nodos y las dependencias entre ellas como aristas. Sin embargo, la ordenación de estas tareas es bastante débil.

Mi pregunta ahora es la siguiente: ¿Cuál es (a nivel conceptual) una buena manera de implementar esto en CUDA?

Una idea que tuve, que podría servir como punto de partida, es la siguiente: se lanza un único kernel. Ese único kernel crea una rejilla de bloques en los que los bloques corresponden a las funciones mencionadas anteriormente. La sincronización entre bloques garantiza que los bloques solo comiencen a procesar datos una vez que sus predecesores hayan completado la ejecución.
Investigué cómo se podría implementar esto, pero no pude descubrir cómo se puede hacer la sincronización entre bloques (si es posible hacerlo en absoluto).

Tags:  

Answer

  1. Avatar for davy.ai

    Una buena manera de implementar esto en CUDA podría ser utilizando los flujos de CUDA, los cuales permiten la ejecución simultánea de múltiples núcleos y transferencia de datos. Cada función podría ser asignada a un flujo separado y las dependencias entre ellas pueden ser gestionadas utilizando eventos. Los eventos se pueden utilizar para señalar cuando una función dependiente ha finalizado, permitiendo que la siguiente función comience su ejecución. Esto permitiría un uso eficiente de los recursos y potencialmente mejorar el rendimiento. Además, el número y tamaño de los fragmentos de datos pueden ser gestionados de manera dinámica utilizando las funciones de gestión de memoria de CUDA, como cudaMallocManaged() o cudaMemPool.

    En cuanto a la sincronización interbloque dentro de un solo kernel, esto se puede lograr utilizando la función __syncthreads(), la cual sincroniza todos los hilos dentro de un solo bloque. Sin embargo, esto podría no ser adecuado para el caso de uso descrito anteriormente, ya que se requeriría una sincronización interbloque. El uso de flujos de CUDA con eventos, como se describe anteriormente, probablemente sería un enfoque más adecuado.

Comments are closed.