2011-10-18 7 views
6

Mi llamada al núcleo falla con "memoria insuficiente". Hace un uso significativo del marco de pila y me preguntaba si este es el motivo de su falla.¿Dónde asigna CUDA el marco de pila para los granos?

Cuando se invoca NVCC con --ptxas-options = -v se imprime la siguiente información de perfil:

150352 bytes stack frame, 0 bytes spill stores, 0 bytes spill loads 
ptxas info : Used 59 registers, 40 bytes cmem[0] 

Hardware: GTX480, SM20, 1,5 GB de memoria del dispositivo, 48KB de memoria compartida/multiprocesador.

Mi pregunta es ¿dónde está asignado el marco de pila: en memoria compartida global, memoria constante, ...?

Intenté con 1 hilo por bloque, así como con 32 hilos por bloque. Mismo "sin memoria".

Otro problema: solo se puede aumentar el número de subprocesos residentes a un multiprocesador si el número total de registros no supera el número de registros disponibles en el multiprocesador (32k para mi tarjeta). ¿Algo similar se aplica al tamaño del marco de pila?

Respuesta

8

La pila está asignada en la memoria local. La asignación es por subproceso físico (GTX480: 15 SM * 1536 subprocesos/SM = 23040 subprocesos). Está solicitando 150,352 bytes/hilo => ~ 3,4 GB de espacio de pila. CUDA puede reducir los hilos físicos máximos por lanzamiento si el tamaño es tan alto. El lenguaje CUDA no está diseñado para tener una gran pila por hilo.

En términos de registros GTX480 está limitado a 63 registros por hilo y 32K registros por SM.

+3

Es correcto que el marco de pila esté asignado en la memoria local. La memoria local reside en la memoria del dispositivo fuera de chip que hace que el acceso (si no está almacenado en caché) sea lento. Sin embargo, citar el número 1536 hilos/SM no es correcto en esta circunstancia y es engañoso. La cantidad total de memoria local requerida para el lanzamiento del kernel depende del número total de subprocesos en la grilla, no de los hilos permitidos máximos por SM y, por lo tanto, depende del tiempo de ejecución. – ritter

+0

@wpunkt Citar 1536 subprocesos/SM es de hecho correcto para gf100 (gtx480) y la memoria local se asigna absolutamente en función del total de subprocesos residentes que no están en el total de subprocesos en el inicio. Un hilo no residente no necesita memoria local. Un hilo retirado no necesita memoria local. La memoria local depende del tiempo de ejecución en que el controlador CUDA aplaza los cambios a la asignación de memoria local hasta el lanzamiento. –

0

El cuadro de apilamiento está muy probablemente en la memoria local.

Creo que hay una cierta limitación del uso de la memoria local, pero incluso sin él, creo CUDA conductor podría asignar más memoria local que sólo por un hilo en su configuración de lanzamiento < < < 1,1 >>>.

De una manera u otra, incluso si logras ejecutar realmente tu código, me temo que puede ser bastante lento debido a todas esas operaciones de pila. Intente reducir el número de llamadas a funciones (por ejemplo, al delimitar esas funciones).

Cuestiones relacionadas