Aquí hay una captura de pantalla de un punto de referencia de caché:
En el punto de referencia, la velocidad de lectura del caché L1 es de aproximadamente 186 GB / s, con una latencia de aproximadamente 3-4 ciclos de reloj. ¿Cómo se alcanza tal velocidad?
Considere la memoria aquí: la velocidad máxima teórica es 665 MHz (frecuencia de memoria) x 2 (velocidad de datos doble) x 64 bits (ancho de bus), que es de aproximadamente 10.6 GB / s, que está más cerca del valor de referencia de 9.6 GB / s .
Pero con el caché L1, incluso si pudiéramos leer en cada ciclo con el procesador a su frecuencia máxima (3 GHz), necesitaríamos alrededor de 496 líneas de datos para lograr un rendimiento que suena poco realista. Esto también se aplica a otros cachés.
¿Qué me estoy perdiendo? ¿Cómo calculamos el rendimiento de un caché a partir de sus parámetros?
fuente
Respuestas:
Esta CPU tiene ...
Como hay dos núcleos, podemos esperar que el punto de referencia ejecute dos subprocesos en paralelo. Sin embargo, su sitio web ofrece muy poca información, pero si miramos aquí , las CPU con más núcleos parecen proporcionar rendimientos L1 correspondientemente más altos. Entonces, creo que lo que se muestra es el rendimiento total con todos los núcleos trabajando en paralelo. Entonces, para su CPU, debemos dividir por dos para un núcleo y un caché:
Ahora, el hecho de "copiar" es 2 veces más rápido que "escribir" es altamente sospechoso. ¿Cómo podría copiar más rápido de lo que puede escribir? Voy a apostar a que lo que muestra el punto de referencia como "copia" es la suma del rendimiento de lectura + escritura, y en este caso leería y escribiría a 45 GB / s, pero mostraría 90, porque es un punto de referencia, y ¿Quién demonios confía en los puntos de referencia? Así que ignoremos "copiar".
Ahora, un registro de 128 bits tiene 16 bytes, lo suficientemente cerca, por lo que parece que este caché puede hacer dos lecturas de 128 bits y una escritura por reloj.
Esto es exactamente lo que realmente desea optimizar esas instrucciones de descifrado de números SSE: dos lecturas y una escritura por ciclo.
Lo más probable es que esto se implemente con muchas líneas de datos paralelas, que es la forma habitual de transportar muchos datos muy rápido dentro de un chip.
fuente
a[i] = b[i] + c[i]
). Por cierto, Intel Haswell y más tarde tienen una AGU de tienda en el puerto 7 que puede manejar modos de direccionamiento simples (no indexados), por lo que pueden ejecutar 2 cargas + 1 Uops de tienda por reloj. (Y la ruta de datos a L1D es 256b, por lo que duplica el ancho de banda de L1D). Vea el artículo de David Kanter: realworldtech.com/haswell-cpu/5La respuesta de @peufeu señala que estos son anchos de banda agregados de todo el sistema. L1 y L2 son cachés privados por núcleo en la familia Intel Sandybridge, por lo que los números son el doble de lo que puede hacer un solo núcleo. Pero eso todavía nos deja con un ancho de banda impresionantemente alto y una baja latencia.
El caché L1D está integrado directamente en el núcleo de la CPU, y está muy unido a las unidades de ejecución de carga (y al búfer de almacenamiento) . Del mismo modo, el caché L1I está justo al lado de la parte de extracción / decodificación de instrucciones del núcleo. (En realidad, no he mirado un plano de silicio de Sandybridge, por lo que esto podría no ser literalmente cierto. La parte de problema / cambio de nombre del front-end probablemente esté más cerca del caché de UOP decodificado "L0", que ahorra energía y tiene un mejor ancho de banda que los decodificadores.)
¿Por qué parar ahí? Intel desde Sandybridge y AMD desde K8 pueden ejecutar 2 cargas por ciclo. Los cachés multipuerto y los TLB son una cosa.
Escritura de microarquitectura Sandybridge de David Kanter tiene un buen diagrama (que también se aplica a su CPU IvyBridge):
(El "planificador unificado" contiene ALU y uops de memoria esperando que sus entradas estén listas, y / o esperando su puerto de ejecución. (Por ejemplo,
vmovdqa ymm0, [rdi]
decodifica a un uop de carga que tiene que esperarrdi
si un previoadd rdi,32
aún no se ha ejecutado, para ejemplo). Intel programa uops a puertos en el momento de emisión / cambio de nombre . Este diagrama solo muestra los puertos de ejecución para uops de memoria, pero ALU uops no ejecutados también compiten por él. La etapa de emisión / cambio de nombre agrega uops al ROB y al planificador Permanecen en el ROB hasta la jubilación, pero en el planificador solo hasta el envío a un puerto de ejecución (esta es la terminología de Intel; otras personas usan el problema y el envío de manera diferente). AMD usa planificadores separados para enteros / FP, pero los modos de direccionamiento siempre usan registros enterosComo muestra eso, solo hay 2 puertos AGU (unidades de generación de direcciones, que toman un modo de direccionamiento similar
[rdi + rdx*4 + 1024]
y producen una dirección lineal). Puede ejecutar 2 operaciones de memoria por reloj (de 128b / 16 bytes cada una), hasta una de ellas es una tienda.Pero tiene un truco bajo la manga: SnB / IvB ejecuta 256b AVX cargas / tiendas como una sola unidad que toma 2 ciclos en un puerto de carga / tienda, pero solo necesita la AGU en el primer ciclo. Eso permite que una unidad de dirección de tienda se ejecute en la AGU en el puerto 2/3 durante ese segundo ciclo sin perder ningún rendimiento de carga. Entonces, con AVX (que las CPU Intel Pentium / Celeron no admiten: /), SnB / IvB puede (en teoría) soportar 2 cargas y 1 tienda por ciclo.
Su CPU IvyBridge es el modelo de Sandybridge (con algunas mejoras microarquitectónicas, como la eliminación de mov , ERMSB (memcpy / memset) y la captación previa de hardware de la página siguiente). La generación posterior a eso (Haswell) duplicó el ancho de banda L1D por reloj al ampliar las rutas de datos desde las unidades de ejecución a L1 de 128b a 256b para que las cargas AVX 256b puedan soportar 2 por reloj. También agregó un puerto AGU de tienda adicional para modos de direccionamiento simples.
El rendimiento máximo de Haswell / Skylake es de 96 bytes cargados + almacenados por reloj, pero el manual de optimización de Intel sugiere que el rendimiento promedio sostenido de Skylake (aún suponiendo que no haya fallas L1D o TLB) es de ~ 81B por ciclo. (Un bucle entero escalar puede sostener 2 cargas + 1 tienda por reloj según mi prueba en SKL, ejecutando 7 uops (dominio no fusionado) por reloj desde 4 uops de dominio fusionado. Pero se ralentiza un poco con operandos de 64 bits en lugar de 32 bits, por lo que aparentemente hay un límite de recursos microarquitectónicos y no se trata solo de programar la dirección de la tienda uops al puerto 2/3 y robar ciclos de las cargas).
No puede, a menos que los parámetros incluyan números de rendimiento prácticos. Como se señaló anteriormente, incluso el L1D de Skylake no puede seguir el ritmo de sus unidades de ejecución de carga / almacenamiento para vectores de 256b. Aunque está cerca, y puede para enteros de 32 bits. (No tendría sentido tener más unidades de carga de las que el caché tenía puertos de lectura, o viceversa. Simplemente omitiría el hardware que nunca podría utilizarse por completo. Tenga en cuenta que L1D podría tener puertos adicionales para enviar / recibir líneas a / desde otros núcleos, así como para lecturas / escrituras desde el núcleo).
Solo mirar los anchos y los relojes del bus de datos no te da toda la historia. El ancho de banda de L2 y L3 (y memoria) puede estar limitado por el número de errores pendientes que L1 o L2 pueden rastrear . El ancho de banda no puede exceder la latencia * max_concurrency, y los chips con una latencia más alta L3 (como un Xeon de muchos núcleos) tienen mucho menos ancho de banda L3 de un solo núcleo que una CPU dual / quad core de la misma microarquitectura. Consulte la sección "plataformas vinculadas a la latencia" de esta respuesta SO . Las CPU de la familia Sandybridge tienen 10 memorias intermedias de llenado de línea para rastrear las fallas de L1D (también utilizadas por las tiendas NT).
(El ancho de banda agregado L3 / memoria con muchos núcleos activos es enorme en un Xeon grande, pero el código de un solo subproceso ve un ancho de banda peor que en un núcleo cuádruple a la misma velocidad de reloj porque más núcleos significa más paradas en el bus de anillo, y por lo tanto más alto latencia L3.)
Latencia de caché
La latencia de uso de carga de 4 ciclos de la caché L1D es bastante sorprendente , especialmente teniendo en cuenta que tiene que comenzar con un modo de direccionamiento como
[rsi + 32]
, por lo que tiene que hacer un agregado antes de que incluso tenga una dirección virtual . Luego tiene que traducir eso a físico para verificar las etiquetas de caché para una coincidencia.(Los modos de direccionamiento que no sean
[base + 0-2047]
tomar un ciclo adicional en la familia Intel Sandybridge, por lo que hay un acceso directo en las AGU para modos de direccionamiento simples (típico para casos de persecución de punteros donde la baja latencia de uso de carga es probablemente lo más importante, pero también común en general) (Consulte el manual de optimización de Intel , Sandybridge, sección 2.3.5.2 L1 DCache). Esto también supone que no hay anulación de segmento y una dirección base de segmento de0
, que es normal).También tiene que sondear el búfer de la tienda para ver si se superpone con las tiendas anteriores. Y tiene que resolver esto incluso si una dirección de tienda anterior (en orden de programa) uop no se ha ejecutado todavía, por lo que no se conoce la dirección de tienda. Pero presumiblemente esto puede suceder en paralelo con la comprobación de un golpe L1D. Si resulta que los datos L1D no eran necesarios porque el reenvío de la tienda puede proporcionar los datos del búfer de la tienda, entonces eso no es una pérdida.
Intel usa cachés VIPT (etiquetados físicamente indexados virtualmente) como casi todos los demás, utilizando el truco estándar de tener el caché lo suficientemente pequeño y con una asociatividad lo suficientemente alta como para comportarse como un caché PIPT (sin alias) con la velocidad de VIPT (puede indexarse en paralelo con la TLB virtual-> búsqueda física).
Los cachés L1 de Intel son 32 kB, asociativos de 8 vías. El tamaño de la página es de 4 kB. Esto significa que los bits de "índice" (que seleccionan qué conjunto de 8 formas pueden almacenar en caché cualquier línea dada) están todos debajo del desplazamiento de página; es decir, esos bits de dirección se compensan en una página y siempre son los mismos en la dirección física y virtual.
Para obtener más detalles sobre eso y otros detalles de por qué los cachés pequeños / rápidos son útiles / posibles (y funcionan bien cuando se combinan con cachés más grandes y lentos), vea mi respuesta sobre por qué L1D es más pequeño / rápido que L2 .
Los cachés pequeños pueden hacer cosas que serían demasiado caras en cachés más grandes, como obtener las matrices de datos de un conjunto al mismo tiempo que recuperar etiquetas. Entonces, una vez que un comparador encuentra qué etiqueta coincide, solo tiene que modificar una de las ocho líneas de caché de 64 bytes que ya se obtuvieron de SRAM.
(En realidad no es tan simple: Sandybridge / Ivybridge usa un caché L1D almacenado, con ocho bancos de trozos de 16 bytes. Puede obtener conflictos de banco de caché si dos accesos al mismo banco en diferentes líneas de caché intentan ejecutarse en el mismo ciclo. (Hay 8 bancos, por lo que esto puede suceder con direcciones separadas por un múltiplo de 128, es decir, 2 líneas de caché).
IvyBridge tampoco tiene penalización por acceso desalineado siempre que no cruce un límite de línea de caché de 64B. Supongo que determina qué banco (s) buscar en función de los bits de baja dirección, y configura cualquier cambio necesario para obtener los datos correctos de 1 a 16 bytes.
En las divisiones de línea de caché, sigue siendo solo una única uop, pero tiene múltiples accesos de caché. La penalización sigue siendo pequeña, excepto en divisiones de 4k. Skylake hace que incluso las divisiones de 4k sean bastante baratas, con una latencia de aproximadamente 11 ciclos, igual que una división de línea de caché normal con un modo de direccionamiento complejo. Pero el rendimiento de 4k-split es significativamente peor que el de cl-split sin división.
Fuentes :
fuente
En las CPU modernas, la memoria caché se encuentra justo al lado de la CPU en el mismo troquel (chip) , se hace usando SRAM, que es mucho, mucho más rápido que la DRAM que se usa para los módulos de RAM en una PC.
Por unidad de memoria (un bit o byte), la SRAM es mucho más costosa que la DRAM. Por eso también se usa DRAM en una PC.
Pero dado que SRAM se fabrica con la misma tecnología que la CPU, es tan rápido como la CPU. Además, solo hay buses internos (en la CPU) con los que lidiar, por lo que si necesita ser un bus de 496 líneas de ancho, entonces probablemente lo sea.
fuente
Los cachés L1 son estructuras de memoria bastante amplias. La arquitectura de los cachés L1 en los procesadores Intel se puede encontrar en este manual (proporcionado por next-hack). Sin embargo, la interpretación de algunos parámetros es incorrecta, el "tamaño de línea de caché" no es el "ancho de datos", es el tamaño del bloque de serie del acceso a datos atómicos.
La Tabla 2-17 (sección 2.3.5.1) indica que en las cargas (lecturas), el ancho de banda de caché es 2x16 = 32 Bytes por núcleo por CICLO . Esto solo proporciona un ancho de banda teórico de 96 Gb / s en un núcleo de 3GHz. No está claro qué informa el punto de referencia citado, parece que mide dos núcleos trabajando en paralelo, por lo que genera 192 Gbps para dos núcleos.
fuente
Los retrasos de la puerta son qué? 10 picosegundos? Los tiempos de ciclo para operaciones canalizadas enteras son 333 picosegundos, con varias actividades de decodificación y bus y captura de datos de flip-flop antes de que comience el siguiente ciclo de reloj.
Espero que la actividad más lenta en la lectura de un caché esté esperando que las líneas de datos se separen lo suficiente (probablemente sean diferenciales: una referencia y una carga real del bit de lectura) para que un comparador / pestillo pueda sincronizarse para implementar un positivo. acción de retroalimentación para convertir un pequeño voltaje en un gran cambio de voltaje de nivel lógico de riel a riel (aproximadamente 1 voltio).
fuente
[reg + 0-2047]
), y una búsqueda de TLB, y una comparación de etiquetas (asociativa de 8 vías), y colocar los bytes no alineados de hasta 16 en el puerto de salida de la unidad de carga, para reenviar a otras unidades de ejecución. Es una latencia 4c para un ciclo de persecución de puntero comomov rax, [rax]
.