núcleo cuda infinito

Estoy trabajando en una aplicación para la que es necesario ejecutar un kernel CUDA de forma indefinida. Tengo un hilo de CPU que escribe stg en una lista y gpu lee esa lista y se reinicia (al menos para comenzar). Cuando escribo dentro del kernel

while(true)
{
//kernel code
}

el sistema cuelga. Sé que la GPU todavía está procesando pero, por supuesto, no pasa nada. Y no estoy seguro de que ocurra el reinicio en la lista.

Debo mencionar que la GPU utilizada para los cálculos no se utiliza para la visualización, por lo que no hay problema de vigilancia.

El sistema operativo es Ubuntu 11.10 y cuda toolkit 4.1. Podría usar cualquier ayuda/ejemplos/enlaces para escribir kernel infinito con éxito.

preguntado el 03 de mayo de 12 a las 18:05

El programador CUDA es realmente malo para manejar bucles infinitos, bloqueos de giro, etc., ya que tales "objetos" son totalmente extraños para la arquitectura GPU. Una forma mucho más común y predecible es simplemente ejecutar su kernel de vez en cuando para verificar si han aparecido nuevos elementos. -

Además, los nuevos elementos no pueden simplemente aparecer. Tienes que ponerlos allí. Para que sepa cuándo es necesario volver a ejecutar el kernel. -

El uso de energía en una GPU de gama alta puede aumentar en 250 W cuando se ejecuta un kernel, por lo que hay dinero que ahorrar si se es selectivo con respecto a cuándo ejecutar el kernel. Más ecológico también. -

"el kernel infinito es obligatorio para el proyecto actual. El objetivo es un controlador gpu, por lo que el gpu tiene que funcionar de forma autónoma sin interferencia de la cpu (excepto, por supuesto, para la llamada del kernel)". Toda tu idea suena completamente defectuosa en mi opinión. Deberías volver atrás y repensarlo cuidadosamente. Tome en serio lo que dije antes: los nuevos elementos no pueden aparecer. Tienes que ponerlos allí. Para que sepa cuándo es necesario volver a ejecutar el kernel. -

Para lo que parece ser su problema, desea ejecutar un proceso completo en segundo plano o al menos un hilo, no solo un núcleo CUDA. -

2 Respuestas

El lenguaje de programación CUDA y la arquitectura CUDA actualmente no admiten núcleos infinitos. Le sugiero que considere la sugerencia de Roger.

Si desea continuar con esto, le sugiero que agregue el siguiente código de depuración a su núcleo:

  1. Incremente una variable en la memoria anclada cada N relojes (es posible que desee una ubicación diferente para cada SM) y,
  2. Lea periódicamente una ubicación de memoria que la CPU pueda actualizar para indicarle al kernel que salga.

Este es un perro guardián de software.

Puedes usar clock() o clock64() para controlar la frecuencia con la que haces (1) y (2).

Puede usar cuda-gdb para depurar su problema.

Los bucles infinitos no son compatibles con el idioma. El compilador puede estar eliminando código. Es posible que desee revisar el PTX y el SASS. Si el compilador está generando un código incorrecto, puede falsificarlo haciendo que el compilador piense que hay una condición de salida válida.

contestado el 06 de mayo de 12 a las 02:05

fue una sugerencia inteligente pero no funcionó. No funciona incluso si elimino el tiempo (verdadero) y lo reemplazo con (para int i=0; i<1000; i++). No hay nada malo con el código (en realidad, es realmente simple) y ejecuté el mismo código con éxito en el host. Entiendo que el programador de cuda no maneja bien los bucles, pero he visto muchos ejemplos del kernel ejecutándose dentro de un tiempo o un en bucle. - amanda

Si mantiene los datos en la memoria del sistema anclada, asegúrese de que está haciendo un __theradfence_system para vaciar las escrituras en la memoria del sistema. Si está leyendo un valor, asegúrese de marcarlo como volátil para que el compilador no utilice una lectura anterior en un registro. - Greg Smith

Como ya señaló @Greg Smith, el compilador CUDA no genera un ensamblaje adecuado para bucles infinitos. Y, por supuesto, hay ciertas situaciones en las que es una solución perfecta, por ejemplo, ejecutar un kernel de servicio en segundo plano, que recibe actualizaciones del host, empujado sobre la memoria mapeada del host.

Una solución, que funciona a partir de CUDA 9.2:

volatile int infinity = 1;
while (infinity)
{
  ...
}

Obviamente, hacer un ciclo infinito dentro de una rama divergente no es una buena idea. Aparte de eso, el manejo inadecuado de while (1) construir IMO es definitivamente un error.

Respondido el 12 de junio de 18 a las 12:06

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.