Aquí hay una captura de pantalla de un punto de referencia de caché:
En el punto de referencia, la velocidad de lectura de caché L1 es de aproximadamente 186 GB/s, con una latencia de aproximadamente 3-4 ciclos de reloj. ¿Cómo se logra 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 la caché L1, incluso si pudiéramos leer en cada ciclo con el procesador a su máxima frecuencia (3 GHz), necesitaríamos alrededor de 496 líneas de datos para lograr tal 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?
Esta CPU tiene...
2 núcleos Una instrucción de 32 KB y un caché de primer nivel de datos de 32 KB (L1) para cada núcleo
Dado que hay dos núcleos, podemos esperar que el punto de referencia ejecute dos subprocesos en paralelo. Sin embargo, su sitio web brinda muy poca información, pero si miramos aquí , las CPU con más núcleos parecen brindar rendimientos L1 correspondientemente más altos. Así que 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é:
Read 93 GB/s
Write 47 GB/s
Copy 90 GB/s
Ahora, el hecho de que "copiar" sea 2 veces más rápido que "escribir" es muy sospechoso. ¿Cómo podría copiar más rápido de lo que puede escribir? Apuesto a que lo que muestra el punto de referencia como "copiar" es la suma del rendimiento de lectura y 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 diablos confía en los puntos de referencia? Así que ignoremos la "copia".
Read 93 GB/s => 30 bytes/clock
Write 47 GB/s => 15 bytes/clock
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 le gustaría optimizar realmente esas instrucciones de procesamiento 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.
a[i] = b[i] + c[i]
). Por cierto, Intel Haswell y versiones posteriores tienen una AGU de almacenamiento en el puerto 7 que puede manejar modos de direccionamiento simples (no indexados), por lo que pueden ejecutar 2 operaciones de carga + 1 de almacenamiento por reloj. (Y la ruta de datos a L1D es 256b, por lo que duplica el ancho de banda de L1D). Consulte el artículo de David Kanter: realworldtech.com/haswell-cpu/5La respuesta de @peufeu señala que estos son anchos de banda agregados en 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 aún nos deja con un ancho de banda impresionantemente alto y una baja latencia.
La memoria caché L1D está integrada directamente en el núcleo de la CPU y está muy estrechamente acoplada con las unidades de ejecución de carga (y el búfer de almacenamiento) . De manera similar, el caché L1I está justo al lado de la parte del núcleo para obtener/decodificar instrucciones. (De hecho, no he mirado un plano de planta 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é uop decodificado "L0", que ahorra energía y tiene un mejor ancho de banda que los decodificadores.)
Pero con caché L1, incluso si pudiéramos leer en cada ciclo...
¿Por qué detenerse allí? Intel desde Sandybridge y AMD desde K8 pueden ejecutar 2 cargas por ciclo. Los cachés multipuerto y los TLB son una cosa.
La descripción de la microarquitectura Sandybridge de David Kanter tiene un buen diagrama (que también se aplica a su CPU IvyBridge):
(El "programador unificado" mantiene ALU y uops de memoria esperando que sus entradas estén listas y/o esperando su puerto vmovdqa ymm0, [rdi]
de rdi
ejecución add rdi,32
. 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 las uops de ALU no ejecutadas 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 el retiro, pero en el programador solo hasta que se envían a un puerto de ejecución (esta es la terminología de Intel; otras personas usan emitir y enviar de manera diferente)). AMD usa programadores separados para enteros/FP, pero los modos de direccionamiento siempre usan registros de enteros
Como muestra, 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 que una de ellas sea un almacén.
Pero tiene un truco bajo la manga: SnB/IvB ejecuta cargas/almacenamientos AVX de 256b como un único uop que requiere 2 ciclos en un puerto de carga/almacenamiento, pero solo necesita la AGU en el primer ciclo. Eso permite que una uop de dirección de tienda se ejecute en la AGU en el puerto 2/3 durante ese segundo ciclo sin perder el rendimiento de la carga. Entonces, con AVX (que las CPU Intel Pentium/Celeron no admiten :/), SnB/IvB puede (en teoría) soportar 2 cargas y 1 almacenamiento por ciclo.
Su CPU IvyBridge es la versión reducida de Sandybridge (con algunas mejoras en la microarquitectura, como mov-elimination , ERMSB (memcpy/memset) y búsqueda previa de hardware de página siguiente). La generación posterior (Haswell) duplicó el ancho de banda L1D por reloj al ampliar las rutas de datos de las unidades de ejecución a L1 de 128b a 256b para que las cargas AVX 256b puedan sostener 2 por reloj. También agregó un puerto AGU de almacenamiento 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 (todavía suponiendo que no haya fallas de L1D o TLB) es de ~81B por ciclo. (Un bucle entero escalar puede soportar 2 cargas + 1 tienda por reloj de acuerdo con mis pruebas en SKL, ejecutando 7 uops (dominio no fusionado) por reloj a partir de 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 de microarquitectura y no se trata solo de programar uops de direcciones de tiendas en el puerto 2/3 y robar ciclos de cargas).
¿Cómo calculamos el rendimiento de un caché a partir de sus parámetros?
No puede, a menos que los parámetros incluyan cifras prácticas de rendimiento. Como se señaló anteriormente, incluso el L1D de Skylake no puede mantenerse al día con sus unidades de ejecución de carga/almacenamiento para vectores 256b. Aunque está cerca, y puede serlo para enteros de 32 bits. (No tendría sentido tener más unidades de carga que los puertos de lectura de la memoria caché, 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 dentro del núcleo).
Solo mirar los anchos de bus de datos y los relojes no le da toda la historia. El ancho de banda L2 y L3 (y la memoria) puede estar limitado por la cantidad de fallas pendientes que L1 o L2 pueden rastrear . El ancho de banda no puede exceder la latencia * max_concurrency, y los chips con latencia L3 más alta (como un Xeon de muchos núcleos) tienen mucho menos ancho de banda L3 de un solo núcleo que una CPU de dos o cuatro núcleos de la misma microarquitectura. Consulte la sección "plataformas con límite de latencia" de esta respuesta SO . Las CPU de la familia Sandybridge tienen 10 búferes de relleno de línea para realizar un seguimiento de los errores L1D (también utilizados por las tiendas NT).
(El ancho de banda L3/memoria agregado con muchos núcleos activos es enorme en un Xeon grande, pero el código de subproceso único ve un ancho de banda peor 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 lo tanto, mayor latencia L3.)
¿Cómo se logra tal velocidad?
La latencia de uso de carga de 4 ciclos de la memoria caché L1D es impresionante, pero solo 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 teniendo en cuenta que tiene que comenzar con un modo de direccionamiento como [rsi + rdi * 4 + 32]
, por lo que tiene que generar la dirección antes incluso de tener una dirección virtual . Luego tiene que traducir eso a físico para verificar las etiquetas de caché en busca de una coincidencia.
(Consulte ¿Existe una penalización cuando base+offset está en una página diferente a la base? para obtener más información sobre el [base + 0-2047]
caso especial cuando el base
registro proviene de una carga anterior; parece que Intel sondea de manera optimista el TLB en función de la base
dirección en paralelo con la adición , y tiene que volver a intentar el uop en el puerto de carga si no funciona.Excelente para nodos de lista/árbol con punteros al principio del nodo.
Consulte también el manual de optimización de Intel , sección Sandybridge 2.3.5.2 L1 DCache. Esto también supone que no se anula ningún segmento y que la dirección base del segmento 0
es , lo cual es normal; esos podrían hacerlo peor que 5 ciclos)
El puerto de carga también tiene que sondear el búfer de la tienda para ver si la carga se superpone con las tiendas anteriores. Y tiene que resolver esto incluso si una uop de dirección de tienda anterior (en el orden del programa) aún no se ha ejecutado, por lo que la dirección de la tienda no se conoce (en ese caso, se predice dinámicamente; los errores de predicción causan bombas nucleares en la canalización del orden de la memoria) ). Pero, presumiblemente, esto puede suceder en paralelo con la verificación de un golpe L1D. Si resulta que los datos L1D no eran necesarios porque el reenvío de almacenamiento puede proporcionar los datos del búfer de almacenamiento, entonces no hay pérdida.
Intel usa cachés VIPT (Virtualmente indexadas físicamente etiquetadas) 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 que se comporte como un caché PIPT (sin alias) con la velocidad de VIPT (puede indexar en paralelo con la búsqueda TLB virtual->física).
Los cachés L1 de Intel son de 32 kiB, asociativos de 8 vías. El tamaño de la página es de 4kiB. 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 son el desplazamiento en una página y siempre son los mismos en la dirección virtual y física.
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), consulte mi respuesta sobre por qué L1D es más pequeño/más rápido que L2 .
Los cachés pequeños pueden hacer cosas que serían demasiado costosas en energía en cachés más grandes, como obtener matrices de datos de un conjunto al mismo tiempo que obtener etiquetas. Entonces, una vez que un comparador encuentra qué etiqueta coincide, solo tiene que muxar 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 usan un caché L1D en bancos, con ocho bancos de fragmentos de 16 bytes. Puede tener conflictos entre caché y banco 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 no alineado 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 dirección bajos, y configura cualquier cambio que deba ocurrir para obtener los 1 a 16 bytes de datos correctos.
En las divisiones de línea de caché, sigue siendo solo un único uop, pero tiene múltiples accesos a caché. La penalización sigue siendo pequeña, excepto en divisiones de 4k. Skylake hace que incluso las divisiones de 4k sean bastante económicas, con una latencia de aproximadamente 11 ciclos, lo mismo 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 cl-split non-split.
Fuentes :
En las CPU modernas, la memoria caché se encuentra justo al lado de la CPU en el mismo troquel (chip) , está hecha con SRAM , que es mucho, mucho más rápida que la DRAM que se usa para los módulos de RAM en una PC.
Por unidad de memoria (un bit o un byte), la SRAM es mucho más cara que la DRAM. Es por eso que DRAM también se usa en una PC.
Pero como la SRAM está hecha con la misma tecnología que la propia CPU, es tan rápida 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.
Las cachés L1 son estructuras de memoria bastante amplias. La arquitectura de las 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 en serie de acceso a datos atómicos.
La Tabla 2-17 (sección 2.3.5.1) indica que en 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 3 GHz. 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.
¿Los retrasos en la puerta son qué? 10 picosegundos? Los tiempos de ciclo para todas las operaciones canalizadas son de 333 picosegundos, con varias actividades de decodificación y de 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é sea esperar a 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 se pueda sincronizar un comparador/bloqueo para implementar un positivo- acción de retroalimentación para convertir un pequeño voltaje en una gran oscilación de voltaje de nivel lógico de riel a riel (alrededor de 1 voltio).
[reg + 0-2047]
), una búsqueda de TLB y una comparación de etiquetas (asociación de 8 vías), y colocar los hasta 16 bytes no alineados resultantes en el puerto de salida de la unidad de carga, para reenvío a otras unidades de ejecución. Es una latencia de 4c para un bucle de persecución de puntero como mov rax, [rax]
.
usuario16222
Caballero
usuario_1818839
lector de matemáticas
rackandboneman
pedro cordes
rackandboneman
pedro cordes
chrylis -cautelosamente optimista-
Arturo
viejo contador de tiempo
viejo contador de tiempo
pedro cordes
viejo contador de tiempo
viejo contador de tiempo
pedro cordes
pedro cordes
viejo contador de tiempo
pedro cordes