modelo computer performance cpu cpu-architecture tlb

performance - computer - modelo de tlb



¿Qué sucede después de una falla L2 TLB? (1)

Las microarquitecturas modernas x86 tienen un hardware dedicado al recorrido de la página . Incluso pueden hacer especulativos recorridos de página para cargar entradas TLB antes de que ocurra una falla TLB . Skylake puede incluso tener dos recorridos de página a la vez, consulte la Sección 2.1.3 del manual de optimización de Intel . Esto puede estar relacionado con la penalización de carga de división de página que cae de 100 a 5 ciclos.

Algunas microarquitecturas lo protegen de los recorridos especulativos de la página al tratarlo como una especulación incorrecta cuando un PTE no almacenado en caché se carga especulativamente pero luego se modifica con una tienda en la tabla de páginas antes del primer uso real de la entrada. es decir, snoop para tiendas a las entradas de la tabla de páginas para entradas TLB solo especulativas que no han sido referenciadas arquitectónicamente por ninguna instrucción anterior. (Win9x dependía de esto, y no romper el código existente importante es algo que les importa a los proveedores de CPU. Cuando se escribió Win9x, las reglas actuales de invalidación de TLB aún no existían, por lo que ni siquiera era un error; vea los comentarios de Andy Glew citados a continuación ) AMD Bulldozer-family viola esta suposición, dándole solo lo que dicen los manuales x86 en papel.

Las cargas de la tabla de páginas generadas por el hardware de recorrido de página pueden afectar a los cachés L1, L2 o L3. Los contadores de rendimiento de Broadwell , por ejemplo, pueden contar las visitas de recorrido de página en su elección de L1, L2, L3 o memoria (es decir, falta de caché). Oprofile lo llama page_walker_loads .

Dado que las tablas de páginas usan un formato de árbol de raíz con entradas de directorio de páginas que apuntan a las tablas de entradas de tablas de páginas, puede valer la pena almacenar en caché PDE (entradas de directorio de páginas) dentro del hardware de recorrido de páginas. Esto significa que necesita vaciar el TLB en casos en los que podría pensar que no es necesario . Intel y AMD realmente hacen esto, de acuerdo con este documento (sección 3) .

Ese documento dice que las cargas de recorrido de página en las CPU AMD ignoran L1, pero pasan por L2. (Quizás para evitar contaminar L1 o para reducir la contención de los puertos de lectura). De todos modos, esto hace que el almacenamiento en caché de algunas PDE de alto nivel (que cubren muchas entradas de traducción diferentes) dentro del hardware de recorrido de la página sea aún más valioso, porque una cadena de búsqueda de punteros es más costosa con una latencia más alta.

Pero tenga en cuenta que x86 no garantiza el almacenamiento en caché negativo de las entradas TLB. Cambiar una página de Inválido a Válido no requiere invlpg . (Entonces, si una implementación real quiere hacer ese tipo de almacenamiento en caché negativo, tiene que espiar o de alguna manera implementar la semántica garantizada por los manuales x86).

(Nota histórica: la respuesta de Andy Glew a un duplicado de esta pregunta sobre electrónica. SE dice que en P5 y anteriores, las cargas de recorrido de página de hardware omitieron el caché interno L1 (pero generalmente era de escritura, por lo que el recorrido de páginas era coherente con las tiendas) IIRC, mi placa base Pentium MMX tenía caché L2 en el mobo, tal vez como caché en el lado de la memoria. Andy también confirma que P6 y luego se cargan desde el caché L1d normal. La otra respuesta también tiene algunos enlaces interesantes al final , incluido el documento que vinculé al final del último párrafo. También parece pensar que el sistema operativo podría actualizar el TLB en sí, en lugar de la tabla de páginas, en un fallo de página (la página de HW no encuentra una entrada), y se pregunta si La caminata de página HW se puede deshabilitar en x86. (Pero en realidad el sistema operativo simplemente modifica la tabla de páginas en la memoria, y al regresar de #PF vuelve a ejecutar la instrucción de falla para que la caminata HW tenga éxito esta vez).

No creo que sea posible deshabilitar HW pagewalk en P5 (o cualquier otro x86). Eso requeriría una forma para que el software actualice las entradas TLB con una instrucción dedicada (no hay una), o con wrmsr o una tienda wrmsr . Confusamente, Andy dice (en un hilo que cité a continuación) que el manejo del software TLB fue más rápido en P5. Creo que quiso decir que habría sido más rápido si hubiera sido posible. Él estaba trabajando en Imation (en MIPS) en ese momento, donde SW page walk es una opción (a veces la única opción), a diferencia de x86 AFAIK.

Como señala Paul Clayton (en otra pregunta sobre fallas de TLB), la gran ventaja de los recorridos de páginas de hardware es que las fallas de TLB no necesariamente detienen la CPU . (La ejecución fuera de orden continúa normalmente, hasta que el búfer de reordenamiento se llena porque la carga / almacén no puede retirarse. El retiro ocurre en orden, porque la CPU no puede comprometer oficialmente nada que no debería haber sucedido si un instrucción anterior fallada.)

Por cierto, probablemente sería posible construir una CPU x86 que maneje las fallas de TLB atrapándolas en un microcódigo en lugar de haber dedicado una máquina de estado de hardware. Esto sería (¿mucho?) Menos eficaz, y tal vez no valga la pena activarlo especulativamente (ya que emitir uops desde un microcódigo significa que no puede emitir instrucciones desde el código que se está ejecutando).

El manejo de TLB microcodificado en teoría podría no ser terrible si ejecuta esos uops en un hilo de hardware separado ( idea interesante ), estilo SMT. Necesitaría tener una carga de inicio / parada mucho menor que Hyperthreading normal para cambiar de un solo subproceso a ambos núcleos lógicos activos (tiene que esperar a que se agoten las cosas hasta que pueda dividir el ROB, almacenar la cola, etc.) porque se iniciará / detendrá con mucha frecuencia en comparación con un núcleo lógico habitual. Pero eso puede ser posible si no es realmente un hilo completamente separado, sino solo un estado de retiro separado, por lo que la memoria caché no funciona, no bloquea el retiro del código principal y hace que use un par de registros internos ocultos para los temporales. El código que tiene que ejecutar es elegido por los diseñadores de la CPU, por lo que el subproceso HW adicional no tiene que estar cerca del estado arquitectónico completo de un núcleo x86. Rara vez tiene que hacer ninguna tienda (¿tal vez solo para las banderas a las que se accede en PTE?), Por lo que no sería malo permitir que esas tiendas usen la misma cola de la tienda que el hilo principal. Simplemente dividiría el front-end para mezclar los uops de administración de TLB y dejarlos ejecutar fuera de orden con el hilo principal. Si pudieras mantener pequeño el número de saltos por paso de página, podría no ser muy bueno.

En realidad, ninguna CPU realiza recorridos de página "HW" con microcódigo en un subproceso HW separado que conozco, pero es una posibilidad teórica.

En algunas arquitecturas RISC (como MIPS), el núcleo del sistema operativo es responsable de manejar las fallas de TLB . Las fallas de TLB resultan en la ejecución del controlador de interrupción de fallas de TLB del núcleo. Esto significa que el sistema operativo es libre de definir su propio formato de tabla de páginas en tales arquitecturas. Supongo que marcar una página como sucia después de una escritura también requiere una trampa en una rutina proporcionada por el sistema operativo, ya que la CPU no sabe sobre el formato de la tabla de páginas.

Este capítulo de un libro de texto de sistemas operativos explica la memoria virtual, las tablas de páginas y los TLB. Describen la diferencia entre los TLB administrados por software (MIPS, SPARCv9) y los TLB administrados por hardware (x86).

Como se mencionó anteriormente, la administración de SW TLB es una opción en x86 si deshabilita la función de recorrido de página HW, y fue una victoria en P5.

Otros enlaces:

Comentarios sobre la coherencia TLB de Andy Glew, uno de los arquitectos de Intel P6 (Pentium Pro / II / III), luego trabajó en AMD.

La razón principal por la que Intel comenzó a ejecutar la tabla de páginas recorre la memoria caché, en lugar de omitir la memoria caché, fue el rendimiento. Antes de la página P6, los recorridos de la tabla eran lentos, no se beneficiaban del caché y no eran especulativos. Lo suficientemente lento como para que el manejo de errores de TLB de software fuera una victoria de rendimiento 1 . P6 acelerado TLB falla al hacerlos especulativamente, usar el caché y también al almacenar en caché los nodos intermedios como las entradas del directorio de páginas.

Por cierto, AMD era reacio a hacer el manejo de fallas TLB especulativamente. Creo que porque fueron influenciados por los arquitectos DEC VAX Alpha. Uno de los arquitectos de DEC Alpha me dijo enfáticamente que el manejo especulativo de las fallas de TLB, como lo estaba haciendo P6, era incorrecto y nunca funcionaría. Cuando llegué a AMD alrededor de 2002, todavía tenían algo llamado "Valla TLB", no una instrucción de valla, sino un punto en la secuencia de rop o microcódigo donde TLB falla o no se podía permitir que ocurriera. Me temo que No recuerdo exactamente cómo funcionó.

así que creo que no es tanto que Bulldozer abandonó la coherencia TLB y la anotación de la tabla de páginas, lo que sea que eso signifique, ya que Bulldozer pudo haber sido la primera máquina AMD en hacer un manejo de fallas TLB moderadamente agresivo.

recuerde que cuando se inició P6, P5 no se estaba enviando: todos los x86es existentes omitieron la tabla de la página de la memoria caché en orden, no especulativamente, sin captaciones previas asincrónicas, sino en cachés de escritura. Es decir, FUERON coherentes en caché, y el sistema operativo podría confiar en el reemplazo determinista de las entradas TLB. IIRC I escribió esas reglas arquitectónicas sobre la capacidad de almacenamiento en caché especulativa y no determinista, tanto para entradas TLB como para cachés de datos e instrucciones. No puede culpar a los sistemas operativos como Windows y UNIX y Netware por no seguir la tabla de páginas y las reglas de administración de TLB que no existían en ese momento.

IIRC I escribió esas reglas arquitectónicas sobre la capacidad de almacenamiento en caché especulativa y no determinista, tanto para entradas TLB como para cachés de datos e instrucciones. No puede culpar a los sistemas operativos como Windows y UNIX y Netware por no seguir la tabla de páginas y las reglas de administración de TLB que no existían en ese momento.

Nota a pie de página 1: que yo sepa, ninguna CPU x86 ha admitido la administración de software TLB. Creo que Andy quería decir "habría sido más rápido" en P5, porque de todos modos no podría ser especulativo o fuera de orden, y ejecutar instrucciones x86 con direcciones físicas (paginación desactivada para evitar un catch-22) habría permitido almacenamiento en caché de cargas de tablas de páginas. Quizás Andy estaba pensando en MIPS, que era su trabajo diario en ese momento.

Más de Andy Glew del mismo hilo , porque estos comentarios merecen estar en una respuesta completa en alguna parte.

(2) uno de mis mayores remordimientos wrt P6 es que no proporcionamos compatibilidad de coherencia TLB intrainstrucción. Algunas instrucciones acceden a la misma página más de una vez. Era posible que diferentes uops en la misma instrucción obtuvieran diferentes traducciones para la misma dirección . Si le hubiéramos dado al microcódigo la capacidad de guardar una traducción de dirección física, y luego usarla, las cosas habrían sido mejores en mi humilde opinión.

(2a) Yo era un defensor de RISC cuando me uní a P6, y mi actitud era "dejar que SW (microcódigo) lo haga".

(2a '') uno de los errores más vergonzosos estaba relacionado con agregar con llevar a la memoria. A principios de microcódigo. La carga iría, la bandera de transporte se actualizaría y la tienda podría fallar, pero la bandera de transporte ya se había actualizado, por lo que la instrucción no se pudo reiniciar. // era una solución simple de microcódigo, que hacía la tienda antes de que se escribiera el indicador de acarreo, pero una uop adicional fue suficiente para que esa instrucción no encajara en el sistema de ucode de "velocidad media".

(3) De todos modos, el principal "soporte" que P6 y sus descendientes dieron para manejar los problemas de coherencia de TLB fue volver a recorrer las tablas de páginas al momento de la jubilación antes de informar una falla. Esto evitó confundir al sistema operativo al informar un error cuando las tablas de páginas decían que no debería haber uno.

(4) meta comentario: no creo que ninguna arquitectura haya definido correctamente las reglas para el almacenamiento en caché de entradas TLB no válidas. // AFAIK la mayoría de los procesadores no almacenan en caché entradas TLB no válidas, excepto posiblemente Itanium con sus páginas NAT (no es una cosa). Pero hay una necesidad real: los accesos especulativos a la memoria pueden ser direcciones salvajes, perder el TLB, hacer un recorrido costoso por la tabla de páginas, ralentizar otras instrucciones y subprocesos, y luego hacerlo una y otra vez porque "esto es malo dirección, no es necesario caminar por las tablas de páginas "no se recuerda. // Sospecho que los ataques de DOS podrían usar esto.

(4 '') peor, los sistemas operativos pueden hacer suposiciones implícitas de que las traducciones no válidas nunca se almacenan en caché y, por lo tanto, no hacen una invalidación de TLB o un derribo de MP TLB cuando se pasa de inválido a válido. // Peor ^ 2: imagine que está almacenando en caché los nodos interiores del caché de la tabla de páginas. Imagine que PD contiene todos los PDE inválidos; peor ^ 3, que el PD contiene d PDE válidos que apuntan a PT que no son válidos. ¿Todavía puede almacenar en caché esas PDE? ¿Exactamente cuándo necesita el SO invalidar una entrada?

(4 '''') debido a que los derribos de MP TLB usando interrupciones entre procesadores eran caros, los encargados del rendimiento del sistema operativo (como solía ser) siempre hacen argumentos como "no necesitamos invalidar el TLB después de cambiar un PTE de inválido a válido" o "de lectura válida a escritura válida con una dirección diferente". O "no necesitamos invalidar el TLB después de cambiar un PDE para apuntar a un PT diferente cuyos PTE sean exactamente iguales al PT original ...". // Muchos argumentos ingeniosos geniales. Lamentablemente no siempre es correcto.

Algunos de mis amigos arquitectos informáticos ahora adoptan TLB coherentes: TLB que snoop escribe al igual que los cachés de datos. Principalmente para permitirnos construir TLB aún más agresivos y cachés de tablas de páginas, si son entradas válidas e inválidas de los nodos hoja e interior. Y no tener que preocuparse por los supuestos de los chicos del sistema operativo. // Todavía no estoy allí: demasiado caro para hardware de gama baja. Pero podría valer la pena hacerlo en el extremo superior.

yo: Santo cielo, ¿de ahí viene ese ALU uop extra en ADC de destino de memoria, incluso en Core2 y SnB-family? Nunca lo habría adivinado, pero me había dejado perplejo.

Andy: a menudo cuando "haces lo de RISC" se requieren instrucciones adicionales o microinstrucciones, en un orden cuidadoso. Mientras que si tiene soporte "CISCy", como soporte especial de hardware para que una sola instrucción sea una transacción, ya sea todo hecho o no hecho, se pueden usar secuencias de código más cortas.

Algo similar se aplica al código de modificación automática: no era tanto que quisiéramos hacer que el código de modificación automática se ejecutara rápidamente, sino que tratar de hacer que los mecanismos heredados para el código de modificación automática, drenando la tubería para instrucciones de serialización como CPUID, fueran más lentos que simplemente husmeando el Icache y la tubería. Pero, de nuevo, esto se aplica a una máquina de gama alta: en una máquina de gama baja, los mecanismos heredados son lo suficientemente rápidos y baratos.

Lo mismo ocurre con los pedidos de memoria. De gama alta husmeando más rápido; drenaje de gama baja más barato.

Es difícil mantener esta dicotomía.

Es bastante común que una implementación particular tenga que implementar reglas compatibles pero más fuertes que la declaración arquitectónica . Pero no todas las implementaciones tienen que hacerlo de la misma manera.

Este hilo de comentarios estaba en la respuesta de Andy a una pregunta sobre el código auto modificable y ver instrucciones obsoletas; otro caso en el que las CPU reales van más allá de los requisitos en papel, porque en realidad es más fácil espiar siempre las tiendas cerca de EIP / RIP que volver a sincronizar solo las instrucciones de las sucursales si no realiza un seguimiento de lo que sucedió entre las sucursales.

¿Me cuesta entender qué sucede cuando los dos primeros niveles del búfer de traducción Lookaside resultan en errores?

No estoy seguro de si se produce "recorrido de página" en un circuito de hardware especial, o si las tablas de páginas se almacenan en el caché L2 / L3, o si solo residen en la memoria principal.