Cómo diseñar chips de GPU
Chapter 5 Gpu Memory System Design

Capítulo 5: Diseño del sistema de memoria GPU

Las Unidades de Procesamiento Gráfico (GPU) han evolucionado hasta convertirse en aceleradores altamente paralelos y programables capaces de alcanzar un alto rendimiento y eficiencia energética en una amplia gama de aplicaciones. El sistema de memoria es un componente crítico de las arquitecturas GPU modernas, ya que debe suministrar a una gran cantidad de hilos concurrentes un acceso rápido a los datos. En este capítulo, exploraremos los elementos clave del diseño del sistema de memoria GPU, incluyendo las tecnologías DRAM utilizadas en las GPU, los controladores de memoria y arbitraje, la memoria compartida y las cachés, y las técnicas para una utilización eficiente de la memoria.

Tecnologías DRAM para GPUs

La Memoria de Acceso Aleatorio Dinámico (DRAM) es la tecnología principal utilizada para implementar la memoria principal en los sistemas informáticos modernos, incluidas las GPU. La DRAM ofrece alta densidad y un costo relativamente bajo en comparación con otras tecnologías de memoria. Sin embargo, la DRAM también tiene una latencia de acceso más alta y un ancho de banda más bajo en comparación con las memorias en chip como las cachés y los archivos de registro.

Las GPU suelen emplear tecnologías DRAM especializadas que están optimizadas para un alto ancho de banda en lugar de baja latencia. Algunas de las tecnologías DRAM más comunes utilizadas en las GPU incluyen:

  1. GDDR (Graphics Double Data Rate): GDDR es una tecnología DRAM especializada diseñada para tarjetas gráficas y consolas de videojuegos. Ofrece un ancho de banda más alto que la DRAM DDR estándar al utilizar un bus más ancho y velocidades de reloj más altas. GDDR5 y GDDR6 son las versiones más recientes, que ofrecen anchos de banda de hasta 512 GB/s y 768 GB/s, respectivamente.

  2. HBM (High Bandwidth Memory): HBM es una tecnología DRAM de alto rendimiento apilada en 3D que proporciona un ancho de banda muy alto y un bajo consumo de energía. HBM apila múltiples dados DRAM uno encima del otro y los conecta utilizando vías de silicio atravesadas (TSV), lo que permite tasas de transferencia de datos mucho más altas que la DRAM tradicional. HBM2 puede proporcionar anchos de banda de hasta 1 TB/s.

La Figura 5.1 ilustra la diferencia entre la memoria GDDR tradicional y la memoria HBM apilada en 3D.

   Memoria GDDR
```Archivo HBM Memory

  ____________                   ______________________  
 |            |                 |  ___________________  |
 |   DRAM     |                 | |                   | |
 |   Chips    |                 | |      Chips DRAM   | |
 |            |                 | |___________________| |
 |            |                 |           .          |
 |            |                 |           .          | 
 |            |                 |           .          |
 |____________|                 |  ___________________  |
      |                         | |                   | |
     PCB                        | |  Lógica Die (GPU) | |
                                | |___________________| |
                                |______________________|

Figura 5.1: Comparación de las arquitecturas de memoria GDDR y HBM.

La elección de la tecnología DRAM depende de los requisitos específicos de la GPU, como el presupuesto de energía, el factor de forma y las aplicaciones objetivo. Las GPU de gama alta para juegos y gráficos profesionales a menudo utilizan GDDR6 por su alta ancho de banda, mientras que el HBM2 es más común en las GPU de centros de datos y HPC donde la eficiencia energética es una preocupación clave.

Controladores de memoria y arbitraje

Los controladores de memoria son responsables de gestionar el flujo de datos entre la GPU y la DRAM fuera del chip. Manejan las solicitudes de memoria de los núcleos de la GPU, programan los comandos DRAM y optimizan los patrones de acceso a la memoria para maximizar la utilización del ancho de banda y minimizar la latencia.

Los controladores de memoria de GPU suelen emplear un diseño multicanal para proporcionar un alto ancho de banda y un acceso paralelo a la DRAM. Cada canal de memoria está conectado a uno o más chips DRAM y tiene sus propios buses de comando y datos. El controlador de memoria distribuye las solicitudes de memoria a través de los canales disponibles para maximizar el paralelismo y evitar conflictos de canal.

La Figura 5.2 muestra un diagrama simplificado de un controlador de memoria de GPU con cuatro canales.

          Núcleos de GPU
              |
        ______|______
       |             |
       |  Contro
```Here is the Spanish translation of the markdown file, with the code comments translated:

| | Controlador de Memoria | |_____________| | | | | Ch0 Ch1 Ch2 Ch3 | | | | DRAM DRAM DRAM DRAM

Figura 5.2: Controlador de memoria GPU con cuatro canales.

La arbitraje de memoria es el proceso de decidir qué solicitudes de memoria deben atenderse primero cuando hay múltiples solicitudes pendientes. Las GPU emplean varias políticas de arbitraje para optimizar el rendimiento y la equidad del sistema de memoria:

1. **Primero en llegar, primero en ser atendido (FCFS)**: La política de arbitraje más simple, donde las solicitudes se atienden en el orden en que llegan. FCFS es justo, pero puede conducir a un rendimiento subóptimo debido a la falta de reordenación de solicitudes.

2. **Ronda Robin (RR)**: Las solicitudes se atienden en un orden cíclico, asegurando la misma prioridad para todos los solicitantes. RR proporciona equidad, pero es posible que no optimice la localidad o la urgencia de las solicitudes.

3. **Basado en prioridad**: A las solicitudes se les asigna prioridad en función de varios criterios, como el tipo de solicitud (por ejemplo, lectura vs. escritura), el origen (por ejemplo, textura vs. caché L2) o la antigüedad de la solicitud. Se atienden primero las solicitudes de mayor prioridad.

4. **Consciente de plazos**: Las solicitudes se programan en función de sus plazos para garantizar su finalización a tiempo. Esto es particularmente importante para aplicaciones gráficas en tiempo real.

5. **Consciente de la localidad**: El controlador de memoria intenta programar las solicitudes que acceden a ubicaciones de memoria cercanas juntas para maximizar los aciertos del búfer de filas y minimizar la sobrecarga de activación y desactivación de DRAM.

Los controladores de memoria GPU avanzados a menudo emplean una combinación de estas políticas de arbitraje para lograr el mejor equilibrio entre rendimiento, equidad y requisitos en tiempo real.

## Memoria compartida y cachés

Las GPU emplean un sistema de memoria jerárquico que incluye tanto cachés gestionadas por software como por hardware para reducir la latencia y la demanda de ancho de banda de la memoria principal.

### Memoria compartida

La memoria compartida es un espacio de memoria gestionado por software, en el chip, que se comparte entre los hilos de un bloque de hilos (NVIDIA) o grupo de trabajo (AMD).Aquí está la traducción al español del archivo markdown "kgroup (OpenCL)". Para el código, no se ha traducido, solo se han traducido los comentarios.

kgroup (OpenCL)

Actúa como una caché controlada por el usuario, lo que permite a los programadores administrar explícitamente el movimiento de datos y reutilización dentro de un bloque de subprocesos.

La memoria compartida se implementa típicamente utilizando bancos de SRAM rápidos y con varios puertos para proporcionar acceso de baja latencia y alto ancho de banda. Cada banco puede atender una solicitud de memoria por ciclo, por lo que el hardware debe arbitrar entre los accesos concurrentes al mismo banco para evitar conflictos.

La figura 5.3 ilustra la organización de la memoria compartida en un núcleo de GPU.

Bloque de subprocesos


| _________________ | | | Subproceso 0 | | | || | | . | | . | | . | | _________________ | | | Subproceso N-1| | | || | |_______________| | | | | | Memoria compartida | | ____________ | | | Banco 0 | | | |____| | | | Banco 1 | | | || | | . | | . | | . | | | Banco M-1 | | | |__________| | ||

Figura 5.3: Organización de la memoria compartida en un núcleo de GPU.

El uso adecuado de la memoria compartida puede mejorar significativamente el rendimiento de los kernels de GPU al reducir el número de accesos a la DRAM más lenta y externa. Sin embargo, requiere una programación cuidadosa para asegurar un intercambio de datos eficiente y evitar conflictos de banco.

### Cachés administradas por hardware

Además de la memoria compartida administrada por software, las GPU también emplean cachés administradas por hardware para aprovechar automáticamente la localidad de los datos y reducir los accesos a DRAM. Los tipos más comunes de cachés administradas por hardware en las GPU son:

1. **Caché de datos L1**: Una caché pequeña y por núcleo que almacena los datos de memoria global a los que se accede recientemente. La caché L1 suele ser privada de cada núcleo de GPU y se usa para reducir la latencia de los accesos a la memoria global.

2. **Caché de textura**: Una caché especializada diseñada para optimizar el acceso a los datos de lectura-solo, como los datos de textura.Aquí está la traducción al español de este archivo Markdown, con los comentarios traducidos, pero sin traducir el código:

Datos de textura de GPU. La caché de textura está optimizada para la localidad espacial 2D y admite operaciones de filtrado e interpolación aceleradas por hardware.

3. **Caché constante**: Una caché pequeña y de solo lectura que almacena datos constantes a los que se accede con frecuencia. La caché constante se difunde a todos los subprocesos de una warpa, lo que la hace eficiente para datos que se comparten entre muchos subprocesos.

4. **Caché L2**: Una caché compartida y más grande que se encuentra entre los núcleos GPU y la memoria principal. La caché L2 almacena datos que se expulsan de las cachés L1 y se usa para reducir el número de accesos a DRAM.

La Figura 5.4 muestra una jerarquía de memoria GPU típica con cachés gestionadas por hardware.

Núcleo GPU 0 Núcleo GPU 1 Núcleo GPU N-1


| | | | | | | Caché L1 | | Caché L1 | | Caché L1 | | de datos | | de datos | | de datos | || || || | | | | | | | Caché de | | Caché de | | Caché de | | textura | | textura | | textura | || || || | | | | | | | Caché | | Caché | | Caché | | constante | | constante | | constante | || || |______________| | | | |_________________|_________________| | | | | | Caché L2 | |_____________| | | Memoria principal

Figura 5.4: Jerarquía de memoria GPU con cachés gestionadas por hardware.Aquí está la traducción al español del archivo Markdown, con los comentarios del código traducidos, pero sin traducir el código en sí:

Los caches administrados por hardware ayudan a mejorar el rendimiento de las aplicaciones de GPU al explotar automáticamente la localidad de los datos y reducir el número de accesos a DRAM. Sin embargo, también pueden introducir desafíos de coherencia y consistencia de cache, particularmente en el contexto de modelos de programación paralela como CUDA y OpenCL.

## Técnicas para una Utilización Eficiente de la Memoria

La utilización eficiente del sistema de memoria de la GPU es crucial para lograr un alto rendimiento y una eficiencia energética. Algunas técnicas clave para optimizar el uso de la memoria en aplicaciones de GPU incluyen:

1. **Coalescencia**: Organizar los accesos a memoria de los hilos en una warp a ubicaciones de memoria adyacentes, permitiendo que el hardware los combine en una sola transacción de memoria más amplia. La coalescencia maximiza la utilización del ancho de banda de DRAM y reduce el número de transacciones de memoria.

2. **Optimización del Diseño de Datos**: Organizar las estructuras de datos en memoria para maximizar la localidad espacial y minimizar los fallos de cache. Esto incluye técnicas como el diseño de estructura-de-arreglos (SoA), que agrupa elementos de datos del mismo tipo juntos, y el diseño de arreglo-de-estructuras (AoS), que mantiene los elementos de datos pertenecientes a la misma estructura juntos.

3. **Almacenamiento en Cache y Obtención Anticipada**: Utilizar efectivamente los caches administrados por hardware al explotar la localidad temporal y espacial en los patrones de acceso a memoria. Esto se puede lograr a través de técnicas como división de datos, que divide los datos en trozos más pequeños que se ajustan en la cache, y obtención anticipada de software, que carga explícitamente los datos en la cache antes de que se necesiten.

4. **Programación de Accesos a Memoria**: Reordenar los accesos a memoria para maximizar los aciertos en el búfer de fila y minimizar el sobrecosto de precarga y activación de DRAM. Esto se puede hacer a través de mecanismos de hardware en el controlador de memoria o mediante técnicas de software como optimización de patrones de acceso y transformaciones de diseño de datos.

5. **Compresión**: Aplicar técnicas de compresión de datos para reducir el tamaño de los datos transferidos entre la memoria y los núcleos de la GPU. Esto puede ayudar a reducir el ancho de banda de memoria requerido y mejorar la eficiencia energética.Aquí está la traducción al español del archivo Markdown, con los comentarios traducidos, pero sin traducir el código:

Ayudar a aliviar los cuellos de botella de ancho de banda y reducir el consumo de energía asociado con el movimiento de datos.

6. **Virtualización de Memoria**: Emplear técnicas de memoria virtual para proporcionar un espacio de direcciones unificado y continuo para aplicaciones de GPU. Esto permite una gestión de memoria más flexible y habilita funciones como la paginación a pedido, que pueden ayudar a reducir el uso de memoria y mejorar la utilización del sistema.

La Figura 5.5 ilustra algunas de estas técnicas en el contexto de un sistema de memoria de GPU.

Núcleos de GPU | | | | | Agrupación | || | | | | | Optimización| | del Diseño | | de Datos | || | | | | | Almacenamiento | | en Caché y | | Búsqueda | | Anticipada | || | | | | | Planificación | | de Acceso a | | Memoria | || | | | | | Compresión | || | | | | | Virtualización| | de Memoria | || | DRAM

Figura 5.5: Técnicas para una utilización eficiente de la memoria en un sistema de memoria de GPU.

1. **Agrupación**: Organizar los accesos a memoria de los hilos en una warp hacia ubicaciones de memoria adyacentes, permitiendo que el hardware los combine en una sola transacción de memoria más amplia. La agrupación maximiza la utilización del ancho de banda de DRAM y reduce el número de transacciones de memoria.

   Ejemplo:
   ```c
   // Patrón de acceso sin agrupar
   int idx = threadIdx.x;
   float val = input[idx * stride];
   
   // Patrón de acceso agrupado
   int idx = threadIdx.x;
   float val = input[idx];
  1. Optimización del Diseño de Datos: Organizar las estructuras de datos en la memoria para maximizar la localidad espacial y minimizar los fallos de caché. Esto incluye técnicas como el diseño "estructura-de-arreglos" (SoA), que agrupa los elementos de datos del mismo tipo juntos, y el diseño "arreglo-de-estructuras" (AoS)Aquí está la traducción al español del archivo Markdown, con la traducción de los comentarios, pero sin traducir el código:

  2. Disposición de los datos: Organizar los datos en memoria para mejorar la localidad espacial y temporal de los accesos a memoria. Esto se puede lograr mediante el uso de estructuras de datos específicas, como Array-of-Structures (AoS) y Structure-of-Arrays (SoA), que mantienen los elementos de datos pertenecientes a la misma estructura juntos.

    Ejemplo:

    // Diseño de Array-of-Structures (AoS)
    struct Point {
        float x;
        float y;
        float z;
    };
    Point points[N];
     
    // Diseño de Structure-of-Arrays (SoA)
    struct Points {
        float x[N];
        float y[N];
        float z[N];
    };
    Points points;
  3. Caché y Prefetching: Utilizar eficazmente las cachés gestionadas por hardware mediante la explotación de la localidad temporal y espacial en los patrones de acceso a la memoria. Esto se puede lograr a través de técnicas como el data tiling, que divide los datos en trozos más pequeños que se ajustan a la caché, y el software prefetching, que carga explícitamente los datos en la caché antes de que sean necesarios.

    Ejemplo:

    // Division en trozos de datos
    for (int i = 0; i < N; i += TILE_SIZE) {
        for (int j = 0; j < N; j += TILE_SIZE) {
            // Procesar un trozo de datos que quepa en la caché
            for (int ii = i; ii < i + TILE_SIZE; ii++) {
                for (int jj = j; jj < j + TILE_SIZE; jj++) {
                    // Realizar cálculos en A[ii][jj]
                }
            }
        }
    }
  4. Programación de accesos a memoria: Reordenar los accesos a memoria para maximizar los aciertos en el búfer de fila y minimizar la sobrecarga de precarga y activación de DRAM. Esto se puede hacer a través de mecanismos de hardware en el controlador de memoria o mediante técnicas de software como la optimización de patrones de acceso y transformaciones de diseño de datos.

  5. Compresión: Aplicar técnicas de compresión de datos para reducir el tamaño de los datos transferidos entre la memoria y los núcleos de la GPU. Esto puede ayudar a aliviar los cuellos de botella de ancho de banda y reducir el consumo de energía asociado con el movimiento de datos.

    Ejemplo:

    • Codificación delta: Almacenar las diferencias entre valores consecutivos en lugar de los valores reales.
    • Codificación de longitud de repetición: Reemplazar valores repetidos con una sola instancia y un recuento.
    • Codificación de Huffman: Asignar secuencias de bits más cortas a los valores que ocurren con mayor frecuencia.
  6. Memoria VVirtualización**: Empleo de técnicas de memoria virtual para proporcionar un espacio de direcciones unificado y continuo para aplicaciones de GPU. Esto permite una gestión de la memoria más flexible y permite características como la paginación a demanda, que puede ayudar a reducir la huella de memoria y mejorar la utilización del sistema.

    Ejemplo:

    • Direccionamiento virtual unificado (UVA) en CUDA: Permite que los hilos de GPU accedan directamente a la memoria de la CPU utilizando un solo puntero, simplificando la gestión de la memoria en sistemas heterogéneos.

Tarjetas gráficas de módulo de múltiples chips

A medida que aumentan los requisitos de rendimiento y consumo de energía de las GPU, los diseños tradicionales de chip único es posible que no puedan satisfacer la demanda. Los diseños de módulo de múltiples chips (MCM), donde se integran varios chips de GPU en un solo paquete, han surgido como una solución prometedora a este problema.

Los diseños de GPU MCM ofrecen varias ventajas:

  1. Mayor ancho de banda de memoria: Al integrar múltiples apilados o chips de memoria, las GPU MCM pueden proporcionar un ancho de banda de memoria significativamente mayor en comparación con los diseños de chip único.

  2. Mejor escalabilidad: Los diseños MCM permiten la integración de más unidades de cómputo y controladores de memoria, lo que permite que las GPU escalen a niveles de rendimiento más altos.

  3. Mejor rendimiento y rentabilidad: Los chips individuales más pequeños en un diseño MCM pueden tener mejores rendimientos de fabricación y ser más rentables en comparación con los chips monolíticos grandes.

Sin embargo, los diseños de GPU MCM también introducen nuevos desafíos, como:

  1. Comunicación entre chips: La comunicación eficiente entre los diferentes chips en un paquete MCM es fundamental para el rendimiento. Se requieren interconexiones de alto ancho de banda y baja latencia para minimizar el sobrecargo del movimiento de datos entre los chips.

  2. Suministro de energía y gestión térmica: Los diseños MCM requieren estrategias de suministro de energía y gestión térmica cuidadosas para garantizar un rendimiento y confiabilidad óptimos.

  3. Soporte de software: Es posible que las GPU MCM requieran cambios en el modelo de programación y los sistemas en tiempo de ejecución para aprovechar al máximo los beneficios de la arquitectura de múltiples chips.

La investigación en esteAquí está la traducción al español del archivo Markdown, con los comentarios del código traducidos:

Esta área explora el diseño y la optimización de las GPU MCM, incluyendo la arquitectura del sistema de memoria, el diseño del interconectado y la gestión de recursos.

Por ejemplo, Arunkumar et al. [2017] proponen un diseño de GPU MCM que utiliza un interconectado de alta ancho de banda y baja latencia para conectar múltiples chips GPU. Los autores también proponen una arquitectura de sistema de memoria que aprovecha el mayor ancho de banda y capacidad del diseño MCM para mejorar el rendimiento y la eficiencia energética.

Otro ejemplo es el trabajo de Milic et al. [2018], que propone un esquema de gestión de recursos para GPU MCM que tiene como objetivo mejorar la utilización de recursos y reducir la sobrecarga de la comunicación entre chips. El esquema utiliza una combinación de técnicas de hardware y software para monitorear el uso de recursos y los patrones de comunicación de la aplicación, y tomar decisiones dinámicas de asignación de recursos.

Conclusión

El sistema de memoria es un componente crítico de las arquitecturas GPU modernas, y su diseño y optimización pueden tener un impacto significativo en el rendimiento y la eficiencia general del sistema. A medida que aumentan las demandas de las cargas de trabajo paralelas, los investigadores están explorando una amplia gama de técnicas para mejorar el rendimiento, la escalabilidad y la adaptabilidad de los sistemas de memoria GPU.

Algunas de las principales líneas de investigación en esta área incluyen la programación de accesos a memoria y el diseño de interconectado, la eficacia de la memoria caché, la priorización de solicitudes de memoria y el salto de caché, la explotación de la heterogeneidad entre hilos, el paso de caché coordinado, la gestión adaptativa de la caché, la priorización de la caché, la ubicación de páginas de memoria virtual, la ubicación de datos y los diseños de módulo de múltiples chips.

Al explorar estas y otras técnicas, los investigadores tienen como objetivo desarrollar sistemas de memoria GPU que puedan mantenerse al día con las crecientes demandas de las cargas de trabajo paralelas, manteniendo un alto rendimiento y eficiencia energética. A medida que las GPU continúan evolucionando y encuentran nuevas aplicaciones en áreas como el aprendizaje automático, el cálculo científico y el análisis de datos, el diseño y la optimización de sus sistemas de memoria serán cruciales.Aquí está la traducción al español del archivo markdown:

los tallos seguirán siendo un área importante de investigación e innovación.