La respuesta de @peufeu señala que se trata de anchos de banda agregados en todo el sistema. L1 y L2 son cachés privadas por núcleo en la familia Intel Sandybridge, por lo que las cifras son el doble de lo que puede hacer un solo núcleo. Pero eso nos deja con un ancho de banda impresionantemente alto y una baja latencia.
La memoria caché L1D está integrada en el núcleo de la CPU y está muy acoplada a las unidades de ejecución de carga (y al buffer de almacenamiento) . Del mismo modo, la caché L1I está justo al lado de la parte de obtención/decodificación de instrucciones del núcleo. (En realidad no he mirado un plano de silicio de Sandybridge, así que esto podría no ser literalmente cierto. La parte de emisión/renombrado del front-end está probablemente más cerca de la caché de uop decodificada "L0", que ahorra energía y tiene mejor ancho de banda que los decodificadores).
Pero con la caché L1, incluso si pudiéramos leer en cada ciclo ...
¿Por qué detenerse ahí? Intel desde Sandybridge y AMD desde K8 pueden ejecutar 2 cargas por ciclo. Las cachés multipuerto y los TLB son una cosa.
David Kanter's Resumen de la microarquitectura Sandybridge tiene un bonito diagrama (que también se aplica a tu CPU IvyBridge):
(El "planificador unificado" mantiene las uops de ALU y de memoria a la espera de que sus entradas estén listas, y/o a la espera de su puerto de ejecución. (Por ejemplo vmovdqa ymm0, [rdi]
decodifica a una uop de carga que tiene que esperar a rdi
si un anterior add rdi,32
aún no se ha ejecutado, por ejemplo). Intel programa los uops a los puertos en el momento de la emisión/renombramiento . Este diagrama sólo muestra los puertos de ejecución para las uops de memoria, pero las uops de la ALU no ejecutadas también compiten por ella. La etapa de emisión/renombramiento añade uops a la ROB y al planificador. Permanecen en la ROB hasta que se retiran, pero en el planificador sólo hasta que se envían a un puerto de ejecución. (Esta es la terminología de Intel; otras personas utilizan issue y dispatch de forma diferente)). AMD utiliza programadores separados para enteros / FP, pero los modos de direccionamiento siempre utilizan registros de enteros
Como muestra, sólo hay 2 puertos AGU (unidades de generación de direcciones, que toman un modo de direccionamiento como [rdi + rdx*4 + 1024]
y producir una dirección lineal). Puede ejecutar 2 operaciones de memoria por reloj (de 128b / 16 bytes cada una), siendo una de ellas un almacenamiento.
Pero tiene un truco bajo la manga: el SnB/IvB ejecuta cargas/almacenamientos AVX de 256b como una sola uop que toma 2 ciclos en un puerto de carga/almacenamiento, pero sólo necesita la AGU en el primer ciclo. Esto permite que una uop de almacenamiento de direcciones se ejecute en la AGU en el puerto 2/3 durante ese segundo ciclo sin perder ningún rendimiento de carga. Así que con AVX (que las CPUs Intel Pentium/Celeron no soportan :/), SnB/IvB puede (en teoría) sostener 2 cargas y 1 tienda por ciclo.
Su CPU IvyBridge es el die-shrink de Sandybridge (con algunas mejoras microarquitectónicas, como mov-eliminación (memcpy/memset), y la precarga por hardware de la página siguiente). La generación posterior (Haswell) duplicó el ancho de banda de la L1D por reloj ampliando las rutas de datos de las unidades de ejecución a la L1 de 128b a 256b para que las cargas AVX de 256b puedan soportar 2 por reloj. También añadió un puerto de almacenamiento-AGU adicional para los 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 medio sostenido de Skylake (aún asumiendo que no se pierden L1D o TLB) es de ~81B por ciclo. (Un bucle entero escalar puede sostener 2 cargas + 1 almacén por reloj según mis pruebas en SKL, ejecutando 7 uops (de dominio no fusionado) por reloj a partir de 4 uops de dominio fusionado. Pero se ralentiza un poco con los operandos de 64 bits en lugar de los de 32 bits, así que aparentemente hay algún límite de recursos microarquitectónicos y no es sólo una cuestión de programar uops de almacenamiento de direcciones al puerto 2/3 y robar ciclos de las cargas).
¿Cómo se calcula el rendimiento de una caché a partir de sus parámetros?
No se puede, a menos que los parámetros incluyan números prácticos de rendimiento. Como se ha señalado 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 que puertos de lectura tiene la caché, o viceversa. Sólo dejarías fuera hardware que nunca podría ser utilizado completamente. Ten en cuenta que L1D podría tener puertos extra para enviar/recibir líneas a/desde otros núcleos, así como para lecturas/escrituras desde dentro del núcleo).
El mero hecho de mirar el ancho del bus de datos y los relojes no te da toda la información. El ancho de banda de L2 y L3 (y de la memoria) puede estar limitado por el número de fallos pendientes que L1 o L2 pueden rastrear . El ancho de banda no puede exceder la latencia * max_concurrency, y los chips con L3 de mayor latencia (como un Xeon de muchos núcleos) tienen mucho menos ancho de banda L3 de un solo núcleo que una CPU de doble/cuádruple núcleo de la misma microarquitectura. Véase la sección "plataformas con latencia" de esta respuesta SO . Las CPUs de la familia Sandybridge tienen 10 búferes de relleno de línea para rastrear los fallos de L1D (también utilizados por los almacenes NT).
(El ancho de banda agregado de L3/memoria con muchos núcleos activos es enorme en un Xeon grande, pero el código de un solo hilo ve un peor ancho de banda que en un núcleo cuádruple a la misma velocidad de reloj, porque más núcleos significan más paradas en el bus de anillo y, por tanto, mayor latencia de L3).
Latencia de la caché
¿Cómo se consigue semejante velocidad?
La latencia de uso de carga de 4 ciclos de la caché L1D es impresionante, pero sólo se aplica al caso especial de persecución de punteros (cuando es más importante) . En otros casos son 5 ciclos, lo que sigue siendo impresionante si se tiene en cuenta que tiene que empezar con un modo de direccionamiento como [rsi + rdi * 4 + 32]
por lo que tiene que hacer una generación de direcciones antes de tener una virtual dirección. Luego tiene que traducirlo a físico para comprobar si las etiquetas de la caché coinciden.
(Ver ¿Existe una penalización cuando base+desplazamiento está en una página diferente a la base? para saber más sobre el [base + 0-2047]
caso especial cuando el base
reg proviene de una carga anterior; parece que Intel sondea de forma optimista la TLB basándose en la base
dirección en paralelo con la adición, y tiene que reintentar la uop en el puerto de carga si no funciona. Genial para nodos de lista/árbol con punteros al principio del nodo.
Ver también 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 de 0
que es normal; esos podrían hacer que fuera peor que 5 ciclos)
El puerto de carga también tiene que sondear el buffer de almacenamiento para ver si la carga se solapa con algún almacenamiento anterior. Y tiene que averiguar esto incluso si una uop de dirección de almacenamiento anterior (en el orden del programa) no se ha ejecutado todavía, por lo que la dirección de almacenamiento no se conoce (en ese caso se predice dinámicamente; los errores de predicción causan problemas en la línea de memoria). Pero presumiblemente esto puede ocurrir en paralelo con la comprobación de un éxito L1D. Si resulta que los datos de la L1D no eran necesarios porque el reenvío de la memoria puede proporcionar los datos del buffer de almacenamiento, entonces no hay pérdida.
Intel utiliza cachés VIPT (Virtually Indexed Physically Tagged) como casi todo el mundo, utilizando el truco estándar de tener la caché lo suficientemente pequeña y con una asociatividad lo suficientemente alta como para que se comporte como una caché PIPT (sin aliasing) con la velocidad de VIPT (puede indexar en paralelo con la búsqueda virtual->física de la TLB).
Las cachés L1 de Intel son de 32 kiB, asociativas de 8 vías. El tamaño de la página es de 4 kiB. Esto significa que los bits de "índice" (que seleccionan qué conjunto de 8 vías puede almacenar en caché cualquier línea dada) están todos por debajo del desplazamiento de la página; es decir, esos bits de dirección son el desplazamiento en una página, y son siempre los mismos en la dirección virtual y física.
Para más detalles sobre esto y otros detalles de por qué las cachés pequeñas/rápidas son útiles/posibles (y funcionan bien cuando se combinan con cachés más grandes y lentas), vea mi respuesta en por qué L1D es más pequeño/rápido que L2 .
Las cachés pequeñas pueden hacer cosas que serían demasiado costosas en cachés más grandes, como obtener las matrices de datos de un conjunto al mismo tiempo que se obtienen las etiquetas. Así, una vez que el comparador encuentra la etiqueta que coincide, sólo tiene que muxar una de las ocho líneas de caché de 64 bytes que ya se han obtenido de la SRAM.
(En realidad no es tan sencillo: Sandybridge / Ivybridge utilizan una caché L1D con bancos, con ocho bancos de 16 bytes. Se pueden producir conflictos entre bancos de caché si dos accesos al mismo banco en diferentes líneas de caché intentan ejecutarse en el mismo ciclo. (Hay 8 bancos, así que esto puede ocurrir con direcciones separadas por un múltiplo de 128, es decir, 2 líneas de caché).
IvyBridge tampoco penaliza los accesos no alineados siempre que no crucen un límite de línea de caché de 64B. Supongo que calcula qué banco(s) debe(n) buscar basándose en los bits de dirección bajos, y establece cualquier desplazamiento que deba realizarse para obtener los 1 a 16 bytes de datos correctos.
En las divisiones de líneas de caché, sigue siendo una sola uop, pero hace múltiples accesos a la caché. La penalización sigue siendo pequeña, excepto en las divisiones de 4k. Skylake hace que incluso las divisiones de 4k sean bastante baratas, con una latencia de unos 11 ciclos, la misma que una división de línea de caché normal con un modo de direccionamiento complejo. Pero el rendimiento de las divisiones de 4k es significativamente peor que el de las divisiones sin cl.
Fuentes :