ejemplos - cuda wikipedia
¿Cómo se maneja la memoria CUDA? (2)
Cuando ejecuto mi programa CUDA que asigna solo una pequeña cantidad de memoria global (por debajo de 20 M), recibí un error de "falta de memoria". (De las publicaciones de otras personas, creo que el problema está relacionado con la fragmentación de la memoria) Intento entender este problema y me doy cuenta de que tengo un par de preguntas relacionadas con la administración de la memoria CUDA.
¿Hay algún concepto de memoria virtual en CUDA?
Si solo se permite ejecutar un kernel en CUDA simultáneamente, después de su finalización, ¿se liberará toda la memoria que utilizó o asignó? Si no, ¿cuándo se libera la memoria?
Si se permite que más de un kernel se ejecute en CUDA, ¿cómo pueden asegurarse de que la memoria que usan no se superponga?
¿Alguien puede ayudarme a responder estas preguntas? Gracias
Edición 1: sistema operativo: x86_64 GNU / Linux versión CUDA: 4.0 Dispositivo: Geforce 200, es uno de los GPUS conectados a la máquina, y no creo que sea un dispositivo de visualización.
Editar 2: Lo siguiente es lo que obtuve después de investigar un poco. Sientase libre de corregirme.
CUDA creará un contexto para cada hilo de host. Este contexto mantendrá información tal como qué parte de la memoria (memoria asignada previamente o memoria asignada dinámicamente) se ha reservado para esta aplicación para que otra aplicación no pueda escribir en ella. Cuando finaliza esta aplicación (no kernel), se liberará esta parte de la memoria.
La memoria CUDA se mantiene mediante una lista de enlaces. Cuando una aplicación necesita asignar memoria, pasará por esta lista de enlaces para ver si hay un trozo de memoria continuo disponible para la asignación. Si no puede encontrar ese fragmento, se informará a los usuarios de un error de "falta de memoria", aunque el tamaño total de memoria disponible sea mayor que la memoria solicitada. Y ese es el problema relacionado con la fragmentación de la memoria.
cuMemGetInfo le dirá cuánta memoria es libre, pero no necesariamente cuánta memoria puede asignar en una asignación máxima debido a la fragmentación de la memoria.
En la plataforma Vista (WDDM), la virtualización de memoria GPU es posible. Es decir, múltiples aplicaciones pueden asignar casi toda la memoria de la GPU y WDDM administrará el intercambio de datos a la memoria principal.
Nuevas preguntas: 1. Si la memoria reservada en el contexto se liberará por completo después de que se haya terminado la aplicación, la fragmentación de la memoria no debería existir. Debe haber algún tipo de información en la memoria. 2. ¿Hay alguna forma de reestructurar la memoria de la GPU?
La memoria fuera de chip GPU está separada en memoria global, local y constante. Estos tres tipos de memoria son un concepto de memoria virtual. La memoria global es gratuita para todos los subprocesos, local es solo para un solo subproceso (se utiliza principalmente para el desbordamiento de registros) y la memoria constante es memoria global almacenada en caché (que solo se puede escribir desde el código de host). Eche un vistazo a 5.3.2 de la Guía de programación de CUDA C.
EDITAR: eliminado
La memoria asignada a través de
cudaMalloc
nunca se superpone. Para la memoria que asigna un kernel durante el tiempo de ejecución debería haber suficiente memoria disponible. Si no tiene memoria y trata de iniciar un kernel (solo una suposición), debería recibir el mensaje de error "error desconocido". El controlador que no pudo iniciar y / o ejecutar el kernel.
La memoria del dispositivo disponible para su código en tiempo de ejecución se calcula básicamente como
Free memory = total memory
- display driver reservations
- CUDA driver reservations
- CUDA context static allocations (local memory, constant memory, device code)
- CUDA context runtime heap (in kernel allocations, recursive call stack, printf buffer, only on Fermi and newer GPUs)
- CUDA context user allocations (global memory, textures)
Si recibe un mensaje de falta de memoria, es probable que uno o más de los tres primeros elementos consuman la mayor parte de la memoria de la GPU antes de que el código de usuario intente alguna vez obtener memoria en la GPU. Si, como ha indicado, no está ejecutando una GPU de pantalla, las asignaciones estáticas del contexto son la fuente más probable de su problema. CUDA funciona asignando previamente toda la memoria que requiere el contexto en el momento en que se establece el contexto en el dispositivo. Hay muchas cosas que se asignan para apoyar un contexto, pero el mayor consumidor individual en un contexto es la memoria local. El tiempo de ejecución debe reservar la cantidad máxima de memoria local que cualquier núcleo en un contexto consumirá para la cantidad máxima de subprocesos que cada multiprocesador puede ejecutar simultáneamente, para cada multiproceso en el dispositivo. Esto puede ejecutarse en cientos de Mb de memoria si se carga un kernel pesado de memoria local en un dispositivo con muchos multiprocesadores.
La mejor manera de ver qué puede estar pasando es escribir un programa de host sin código de dispositivo que establezca un contexto y llame a cudaMemGetInfo
. Eso le mostrará la cantidad de memoria que tiene el dispositivo con la mínima carga de contexto en él. Luego ejecuta tu código problemático, agregando la misma llamada cudaMemGetInfo
antes de la primera llamada a cudaMalloc
que luego te dará la cantidad de memoria que está usando tu contexto. Eso podría permitirle conocer a dónde va la memoria. Es muy poco probable que la fragmentación sea el problema si se produce un error en la primera llamada a cudaMalloc
.