¿Cómo se gestiona la memoria CUDA?


Cuando corro mi programa CUDA que asigna solo una pequeña cantidad de memoria global (por debajo de 20 M), obtuve un error de "fuera de memoria". (De los mensajes de otras personas, creo que el problema está relacionado con la fragmentación de la memoria) Trato de entender este problema, y me doy cuenta de que tengo un par de preguntas relacionadas con la gestión de la memoria CUDA.

  1. ¿Hay un concepto de memoria virtual en CUDA?

  2. Si solo se permite que un núcleo se ejecute en CUDA simultáneamente, después de su terminación, ¿se liberará toda la memoria utilizada o asignada? Si no, cuando estos recuerdos se liberaron?

  3. Si se permite ejecutar más de un núcleo en CUDA, ¿cómo pueden asegurarse de que la memoria que utilizan no se superponga?

¿Alguien puede ayudarme a responder estas preguntas? Gracias

Editar 1: sistema operativo: x86_64 GNU / Linux Versión CUDA: 4.0 Dispositivo: Geforce 200, es una de las GPU conectadas a la máquina, y no creo que sea una pantalla dispositivo.

Edit 2: Lo siguiente es lo que obtuve después de hacer un poco de investigación. Siéntete libre de corregirme.

  1. CUDA creará un contexto para cada hilo host. Este contexto guardará información como qué porción de memoria (memoria pre asignada o memoria dinámicamente asignada) se ha reservado para esta aplicación para que otra aplicación no pueda escribir en ella. Cuando esta aplicación termina (no kernel) , esta porción de memoria será lanzar.

  2. 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 fragmento de memoria continua disponible para la asignación. Si no encuentra tal fragmento, un error" fuera de memoria " informará a los usuarios a pesar de que el tamaño total de memoria disponible es mayor que la memoria solicitada. Y ese es el problema relacionado con la fragmentación de la memoria.

  3. CuMemGetInfo le dirá cuánto la memoria es libre, pero no necesariamente la cantidad de memoria que puede asignar en una asignación máxima debido a la fragmentación de la memoria.

  4. En Vista platform (WDDM), es posible la virtualización de memoria GPU. 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á completamente después de que se haya terminado la aplicación, la memoria la fragmentación no debería existir. Debe haber algún tipo de datos en la memoria. 2. ¿Hay alguna forma de reestructurar la memoria de la GPU ?

Author: talonmies, 2011-12-31

2 answers

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 fuera de memoria, es probable que uno o más de los tres primeros elementos consuma la mayor parte de la memoria de la GPU antes de que su código de usuario intente obtener memoria en la GPU. Si, como ha indicado, no se está ejecutando en una GPU de pantalla, entonces las asignaciones estáticas de contexto son la fuente más probable de su problema. CUDA funciona mediante la pre-asignación de toda la memoria a contexto requiere en el momento en que el contexto se establece en el dispositivo. Hay muchas cosas que se asignan para soportar un contexto, pero el mayor consumidor 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 el número máximo de subprocesos que cada multiprocesador puede ejecutar simultáneamente, para cada multiproceso en el dispositivo. Esto puede funcionar en cientos de Mb de memoria si una memoria local el núcleo pesado se carga en un dispositivo con muchos multiprocesadores.

La mejor manera de ver lo que podría estar pasando es escribir un programa host sin código de dispositivo que establezca un contexto y llame a cudaMemGetInfo. Eso le mostrará cuánta memoria tiene el dispositivo con la sobrecarga de contexto mínima en él. Luego ejecute el código problemático, agregando la misma llamada cudaMemGetInfo antes de la primera llamada cudaMalloc que le dará la cantidad de memoria que su contexto está usando. Eso podría permitirte tener una idea de dónde la memoria se va. Es muy poco probable que la fragmentación sea el problema si está recibiendo un fallo en la primera llamada cudaMalloc.

 25
Author: talonmies,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-09 09:50:42
  1. La memoria GPU off-chip 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, la local es solo para un subproceso (se usa principalmente para el derramamiento de registros) y la memoria constante es la memoria global almacenada en caché (solo se puede escribir desde el código del host). Echa un vistazo a 5.3.2 de la Guía de programación de CUDA C.

  2. EDITAR: eliminado

  3. La Memoria asignada a través de cudaMalloc ¿nunca se superponen. Para el la memoria que un núcleo asigna durante el tiempo de ejecución debería tener suficiente memoria disponible. Si no tiene memoria e intenta iniciar un núcleo (solo una suposición mía) debería recibir el mensaje de error "unknown error". El controlador no pudo iniciar y / o ejecutar el núcleo.

 4
Author: Michael Haidl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-31 10:14:37