gpu gpgpu gpu-programming vulkan

¿Qué es la memoria coherente en GPU?



gpgpu gpu-programming (2)

La memoria es la memoria. Pero diferentes cosas pueden acceder a esa memoria. La GPU puede acceder a la memoria, la CPU puede acceder a la memoria, tal vez a otros bits de hardware, lo que sea.

Una cosa en particular tiene acceso "coherente" a la memoria si los cambios realizados por otros en esa memoria son visibles para el lector. Ahora, podrías pensar que esto es una tontería. Después de todo, si se ha cambiado la memoria, ¿cómo es posible que alguien no pueda verla?

En pocas palabras, cachés.

Resulta que cambiar la memoria es costoso. Así que hacemos todo lo posible para evitar cambiar la memoria a menos que sea absolutamente necesario. Cuando escribe un solo byte de la CPU a un puntero en la memoria, la CPU todavía no escribe ese byte. O al menos, no a la memoria. Lo escribe en una copia local de esa memoria llamada "caché".

La razón de esto es que, en general, las aplicaciones no escriben (o leen) bytes individuales. Es más probable que escriban (y lean) muchos bytes, en partes pequeñas. Entonces, si va a realizar una operación costosa como una carga de memoria o un almacenamiento, debe cargar o almacenar una gran parte de la memoria. Por lo tanto, almacena todos los cambios que va a realizar en un caché de la memoria, y luego hace una sola escritura de ese trozo en caché en la memoria real en algún momento en el futuro.

Pero si tiene dos dispositivos separados que usan la misma memoria, necesita alguna forma de asegurarse de que las escrituras de un dispositivo sean visibles para otros dispositivos. La mayoría de las GPU no pueden leer el caché de la CPU. Y la mayoría de los lenguajes de la CPU no tienen soporte en el idioma para decir "hey, esas cosas que escribí en la memoria? Realmente quiero que lo escribas en la memoria ahora". Por lo tanto, normalmente se necesita algo para asegurar la visibilidad de los cambios.

En Vulkan, la memoria que está etiquetada como "HOST_COHERENT" significa que, si escribe en esa memoria (a través de un puntero asignado, ya que esa es la única forma en que Vulkan le permite escribir directamente en la memoria), no necesita usar funciones especiales para hacer Seguro que la GPU puede ver esos cambios. La visibilidad de la GPU de cualquier cambio está garantizada. Si esa marca no está disponible en la memoria, entonces debe usar las API de Vulkan para garantizar la coherencia de las regiones específicas de datos a las que desea acceder.

Con la memoria coherente, una de dos cosas está sucediendo en términos de hardware. El acceso de la CPU a la memoria no se almacena en caché en ninguna de las memorias caché de la CPU, o la GPU tiene acceso directo a las memorias caché de la CPU (tal vez debido a que está en el mismo dado que la (s) CPU (s)). Por lo general, se puede decir que esto último está sucediendo, porque las implementaciones de Vulkan en la GPU en la matriz no se molestan en ofrecer opciones de memoria no coherentes.

No he tropezado ni una sola vez con un término "no coherente" y "coherente" en la memoria

documentos técnicos relacionados con la programación de gráficos. He estado buscando una explicación simple y clara, pero encontré la mayoría de los documentos ''duros'' de this Me complacería recibir una respuesta de estilo laico sobre qué memoria coherente tiene la arquitectura de GPU y cómo funciona. se compara con otros tipos de memoria (probablemente no coherente).


Si la memoria es coherente, todos los subprocesos que accedan a esa memoria deben coincidir con el estado de la memoria en todo momento, por ejemplo: si el subproceso 0 lee la ubicación de la memoria A y el subproceso 1 lee la misma ubicación al mismo tiempo, ambos subprocesos siempre deben leer la misma valor.

Pero si la memoria no es coherente, los hilos A y B pueden leer valores diferentes. El subproceso 0 podría pensar que la ubicación A contiene un 1, mientras que el subproceso cree que esa ubicación contiene un 2. Los diferentes subprocesos tendrían una vista incoherente de la memoria.

La coherencia es difícil de lograr con un alto número de núcleos. A menudo, cada núcleo debe conocer los accesos a la memoria de todos los demás núcleos. Por lo tanto, si tiene 4 núcleos en una CPU de cuatro núcleos, la coherencia no es tan difícil de lograr, ya que cada núcleo debe recibir información sobre las direcciones de acceso a la memoria de otros 3 núcleos, pero en una GPU con 16 núcleos, se debe informar a cada núcleo La memoria accede por otros 15 núcleos. Los núcleos intercambian datos sobre el contenido de su caché utilizando los llamados "protocolos de coherencia de caché".

Es por eso que las GPU a menudo solo admiten formas limitadas de coherencia. Si algunas ubicaciones de memoria son de solo lectura o solo se puede acceder a ellas mediante un único hilo, no se requiere coherencia. Si las memorias caché son pequeñas y no siempre se requiere coherencia, sino solo con instrucciones específicas del programa, es posible lograr el comportamiento correcto del programa utilizando vacíos de memoria caché antes o después de accesos a la memoria específicos.

Si su hardware ofrece tipos de memoria coherentes y no coherentes, entonces puede esperar que la memoria no coherente sea más rápida, pero si intenta ejecutar algoritmos paralelos utilizando esta memoria, fallarán de formas realmente extrañas.