open entre diferencia cuda opencl nvidia bank-conflict

cuda - entre - opengl o opencl



¿Por qué no hay conflictos bancarios en la memoria global para Cuda/OpenCL? (3)

Una cosa que no he descubierto y que Google no me está ayudando, ¿por qué es posible tener conflictos bancarios con la memoria compartida, pero no en la memoria global? ¿Puede haber conflictos bancarios con los registros?

ACTUALIZACIÓN Wow, realmente aprecio las dos respuestas de Tibbit y Grizzly. Parece que solo puedo dar una marca de verificación verde a una respuesta. Soy nuevo para apilar desbordamiento. Supongo que tengo que elegir una respuesta como la mejor. ¿Puedo hacer algo para decir gracias a la respuesta a la que no le doy un cheque verde?


El hecho de que haya o no conflictos bancarios en un tipo dado de memoria depende obviamente de la estructura de la memoria y, por lo tanto, de su propósito.

Entonces, ¿por qué la memoria compartida está diseñada de manera que permita los conflictos bancarios?

Eso es relativamente simple, no es fácil diseñar un controlador de memoria que pueda manejar accesos independientes a la misma memoria simultáneamente (demostrado por el hecho de que la mayoría no puede). Por lo tanto, para permitir que cada subproceso en un semigiro acceda a una palabra direccionada individualmente, se almacena la memoria, con un controlador independiente para cada banco (al menos eso es cómo se puede pensar, no estoy seguro del hardware real). Estos bancos están intercalados para hacer que los subprocesos secuenciales accedan más rápido a la memoria secuencial. Por lo tanto, cada uno de estos bancos puede manejar una solicitud a la vez, lo que idealmente permite la ejecución simultánea de todas las solicitudes en el semigiro (obviamente, este modelo puede teóricamente mantener un mayor ancho de banda debido a la independencia de esos bancos, lo que también es una ventaja).

¿Qué pasa con los registros?

Los registros están diseñados para ser accedidos como operandos para las instrucciones de ALU, lo que significa que deben accederse con una latencia muy baja. Por lo tanto, obtienen más transistores / bit para hacer eso posible. No estoy seguro de cómo se accede exactamente a los registros en los procesadores modernos (no es el tipo de información que necesita a menudo y no es tan fácil de encontrar). Sin embargo, obviamente sería muy poco práctico organizar registros en bancos (para arquitecturas más simples, normalmente se ven todos los registros colgados en un multiplexor grande). Entonces no, no habrá conflictos bancarios para los registros.

Memoria global

En primer lugar, la memoria global funciona en una mayoridad diferente y luego en la memoria compartida. Se accede a la memoria en bloques de 32, 64 o 128 bytes (para GT200 al menos, para fermi siempre es 128B, pero en caché, AMD es un poco diferente), donde cada vez que desea algo de un bloque se accede / transfiere al bloque completo. Es por eso que necesita accesos unidos, ya que si cada hilo accede a la memoria desde un bloque diferente, tiene que transferir todos los bloques.

¿Pero quién dice que no hay conflictos bancarios? No estoy completamente seguro de esto, porque no he encontrado ninguna fuente real que admita esto para el hardware de NVIDIA, pero parece lógico: la memoria global se distribuye normalmente a varios chips ram (que pueden verificarse fácilmente mirando un tarjeta grafica). Tendría sentido, si cada uno de estos chips es como un banco de memoria local, por lo que tendría conflictos bancarios si hay varias solicitudes simultáneas en el mismo banco. Sin embargo, los efectos serían mucho menos pronunciados por una cosa (ya que la mayor parte del tiempo consumido por los accesos a la memoria es la latencia para obtener los datos de A a B de todos modos), y no será un efecto notorio "dentro" de un grupo de trabajo (ya que solo se ejecuta media guerra a la vez y si esa mitad emite más de una solicitud, usted tiene un acceso de memoria no unido, por lo que ya está recibiendo un golpe que dificulta la medición de los efectos de este conflicto. Por lo tanto, solo obtendría conflictos si varios grupos de trabajo intentan acceder al mismo banco. En su situación típica para gpgpu, tiene un gran conjunto de datos en la memoria secuencial, por lo que los efectos no deberían ser notables ya que hay otros grupos de trabajo que acceden a los otros bancos al mismo tiempo, pero debería ser posible construir situaciones en las que el conjunto de datos se centre en unos pocos bancos, lo que supondría un impacto en el ancho de banda (ya que el ancho de banda máximo provendría de la distribución equitativa del acceso en todos los bancos, por lo que cada banco debería sólo tienen una fracción de ese ancho de banda). Una vez más, no he leído nada que demuestre esta teoría para el hardware de nvidia (principalmente, todo se centra en la fusión, lo que por supuesto es más importante, ya que hace que esto no sea un problema para los conjuntos de datos naturales). Sin embargo, de acuerdo con la guía de computación ATI Stream, esta es la situación de las tarjetas Radeon (para 5xxx: los bancos están separados por 2kb y usted quiere asegurarse de que distribuye sus accesos (es decir, de todos los grupos de worgers simuladamente activos) igual a todos los bancos), así que Imaginaría que las tarjetas NVidia se comportan de manera similar.

Por supuesto, para la mayoría de los casos, la posibilidad de conflictos bancarios en la memoria global no es un problema, por lo que en la práctica puede decir:

  • Esté atento a la fusión al acceder a la memoria global
  • Esté atento a los conflictos bancarios al acceder a la memoria local
  • No hay problemas con el acceso a los registros

los múltiples subprocesos que acceden al mismo banco no necesariamente significan que hay un conflicto bancario. Existe un conflicto si los subprocesos desean leer al mismo tiempo desde UNA DIFERENTE FILA dentro del mismo banco.


Respuesta corta: No hay conflictos bancarios ni en la memoria global ni en los registros.

Explicación:

La clave para comprender por qué es captar la granularidad de las operaciones. Un solo hilo no accede a la memoria global. Los accesos a la memoria global están "unidos". Debido a que la memoria global es muy lenta, cualquier acceso de los hilos dentro de un bloque se agrupan para hacer la menor cantidad posible de solicitudes a la memoria global.

Se puede acceder a la memoria compartida por hilos simultáneamente. Cuando dos hilos intentan acceder a una dirección dentro del mismo banco, esto causa un conflicto bancario.

No se puede acceder a los registros por ningún hilo, excepto al que está asignado. Como no puede leer o escribir en mis registros, no puede impedirme que acceda a ellos, por lo que no hay conflictos bancarios.

¿Quién puede leer y escribir en la memoria global?

Only blocks . Un solo hilo puede hacer un acceso, pero la transacción se procesará a nivel de bloque (en realidad, el nivel de warp / half warp, pero estoy intentando que no sea complicado). Si dos bloques acceden a la misma memoria, no creo que tarde más tiempo y puede suceder que el caché L1 se acelere en los dispositivos más nuevos, aunque esto no es evidente de forma transparente.

¿Quién puede leer y escribir en la memoria compartida?

Any thread within a given block. Si solo tiene 1 subproceso por bloque, no puede tener un conflicto bancario, pero no tendrá un rendimiento razonable. Los conflictos bancarios ocurren porque a un bloque se le asignan varios, digamos 512 hilos y todos compiten por direcciones diferentes dentro del mismo banco (no es exactamente la misma dirección). Hay algunas imágenes excelentes de estos conflictos al final de la Guía de programación CUDA C - Figura G2, en la página 167 (en realidad, la página 177 del pdf). Enlace a la versión 3.2

¿Quién puede leer y escribir en los registros?

Only the specific thread to which it is allocated. Por lo tanto, solo un hilo está accediendo a él a la vez.