La 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.)
Pero con el caché L1, incluso si pudiéramos leer en cada ciclo ...
¿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 esperar rdi
si un previo add 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 enteros
Como 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).
¿Cómo calculamos el rendimiento de un caché a partir de sus parámetros?
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é
¿Cómo se alcanza tal velocidad?
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 de 0
, 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 :