Comprensión profunda del principio de almacenamiento en caché TLB

Hoy compartiré un buen artículo sobre TLB, espero que todos solidifiquen sus habilidades básicas y nos permitan comprender el sistema informático en profundidad.

TLB es la abreviatura de búfer de búsqueda de traducción. En primer lugar, sabemos que el papel de la MMU es convertir direcciones virtuales en direcciones físicas.

Cómo funciona la MMU

La relación de mapeo entre la dirección virtual y la dirección física se almacena en la tabla de páginas y ahora la tabla de páginas es jerárquica. Los sistemas de 64 bits son generalmente de 3 a 5 niveles. Una configuración común es una tabla de páginas de 4 niveles, así que tomemos una tabla de páginas de 4 niveles como ejemplo. Son tablas de páginas de cuatro niveles PGD, PUD, PMD y PTE. Habrá un registro de dirección base de la tabla de páginas en el hardware, que almacena la primera dirección de la tabla de páginas PGD.

mecanismo de paginación de Linux

La MMU busca desde la tabla de páginas PGD hasta el PTE de acuerdo con el registro de dirección base de la tabla de páginas y finalmente encuentra la dirección física (la dirección física se almacena en la tabla de páginas PTE). Es como mostrar dónde está tu casa en un mapa. Para encontrar la dirección de tu casa, primero me aseguro de que estás en China, luego me aseguro de que estás en una provincia determinada, continúo hasta una ciudad determinada y finalmente encuentro tu casa. Es el mismo principio. Encuéntralo paso a paso. También has visto este proceso, es muy engorroso. Si descubro la ubicación específica de su casa por primera vez, anotaré su nombre y la dirección de su casa. La próxima vez que busques, solo tienes que decirme cuál es tu nombre, y podré decirte la dirección directamente, sin tener que buscar nivel por nivel.

El proceso de búsqueda en la tabla de páginas de cuatro niveles requiere cuatro accesos a la memoria. Se puede imaginar el retraso, que afecta en gran medida el rendimiento. En la siguiente figura se muestra un ejemplo del proceso de búsqueda de la tabla de páginas. Habrá una oportunidad de expandirse en detalle en el futuro, solo infórmese aquí.

paseo de la mesa de página

¿Cuál es la naturaleza de TLB?

El TLB es en realidad un caché.

Caché de datos Dirección de caché (dirección virtual o dirección física) y datos. El TLB almacena en caché las direcciones virtuales y sus direcciones físicas asignadas. El TLB busca el caché en función de la dirección virtual y no tiene más remedio que buscar en función de la dirección virtual.

Entonces, el TLB es un caché virtual. Una vez que la TLB existe en el hardware, el proceso de traducción de la dirección virtual a la dirección física ha cambiado. La dirección virtual primero se envía a la TLB para confirmar si llega a la memoria caché y, si la memoria caché llega, la dirección física se puede obtener directamente.

De lo contrario, busque la tabla de páginas nivel por nivel para obtener la dirección física. Y almacene en caché la relación de mapeo entre la dirección virtual y la dirección física en el TLB. Dado que el TLB es un caché virtual (VIVT), ¿hay problemas de alias y ambigüedad? Si es así, ¿cómo trabajan juntos el software y el hardware para resolver estos problemas?

TLB especial

La unidad más pequeña de dirección física de asignación de dirección virtual es 4 KB. Por lo tanto, la TLB en realidad no necesita almacenar los 12 bits inferiores de la dirección virtual y la dirección física (debido a que los 12 bits inferiores son iguales, no es necesario almacenarlos en absoluto).

Además, si golpeamos el caché, debemos sacar todos los datos del caché de una vez. Entonces, la dirección virtual no necesita el campo de compensación. ¿Es obligatorio el campo de índice? Depende de cómo esté organizado el caché.

Si es un caché totalmente asociativo. Entonces no hay necesidad de index. Si utiliza una memoria caché asociada a un conjunto multidireccional, aún se requiere un índice.

La siguiente figura es un ejemplo de un TLB asociado a un conjunto de cuatro vías. El rango de direccionamiento de CPU de 64 bits actual no se amplía a 64 bits. El espacio de direcciones de 64 bits es muy grande y no es tan grande hoy en día.

Por lo tanto, para simplificar el diseño o resolver el costo del hardware, solo se utiliza una parte de los bits de dirección virtual reales. Aquí tomamos como ejemplo el bus de direcciones de 48 bits.

Problema de aliasing con TLB

Permítanme pensar primero en la primera pregunta, si existe el alias. Sabemos que no hay problema de alias en el caché de datos de PIPT. La dirección física es única y una dirección física debe corresponder a un dato. Pero diferentes direcciones físicas pueden almacenar los mismos datos.

Es decir, el dato correspondiente a la dirección física es una relación de uno a uno, y viceversa es una relación de muchos a uno. Debido a la particularidad de la TLB, se almacena la correspondencia entre direcciones virtuales y direcciones físicas.

Por lo tanto, para un solo proceso, una dirección virtual corresponde a una dirección física al mismo tiempo, y una dirección física puede ser mapeada por varias direcciones virtuales.

Comparando la memoria caché de datos PIPT con TLB, podemos saber que no hay problema de alias en TLB. Sin embargo, hay un problema de alias en VIVT Cache, porque VA debe convertirse en PA y los datos se almacenan en PA. Hay muchas historias en el medio, por lo que se han introducido algunos problemas.

Problema de ambigüedad de TLB

Sabemos que el rango de direcciones virtuales visto entre diferentes procesos es el mismo, por lo que bajo múltiples procesos, la misma dirección virtual de diferentes procesos puede asignarse a diferentes direcciones físicas. Esto crea problemas de ambigüedad.

Por ejemplo, el proceso A asigna la dirección 0x2000 a la dirección física 0x4000. El proceso B asigna la dirección 0x2000 a la dirección física 0x5000. Cuando se ejecuta el proceso A, almacene en caché la relación de asignación entre 0x2000 y 0x4000 en TLB. Cuando se cambia el proceso B, el proceso B accede a los datos en 0x2000 y obtendrá datos de la dirección física 0x4000 debido a un acierto de TLB.

Esto crea ambigüedad. Cómo eliminar esta ambigüedad, podemos aprender del método de procesamiento de caché de datos VIVT e invalidar todo el TLB durante el cambio de proceso. Ninguno de los procesos conmutados alcanzará la TLB, pero provocará una pérdida de rendimiento.

  Información a través del tren: ruta de aprendizaje de la tecnología del código fuente del kernel de Linux + video tutorial del código fuente del kernel

Aprendizaje a través del entrenamiento: código fuente del kernel de Linux, ajuste de memoria, sistema de archivos, gestión de procesos, controlador de dispositivo/pila de protocolo de red

Cómo evitar la descarga de TLB tanto como sea posible

Lo primero que hay que explicar es que el color aquí se entiende como invalidante. Sabemos que cuando se cambia el proceso, para evitar ambigüedades, necesitamos vaciar activamente todo el TLB. Flush TLB se puede evitar si podemos distinguir las entradas de TLB de diferentes procesos.

Sabemos cómo Linux distingue diferentes procesos, y cada proceso tiene una ID de proceso única. ¡Sería genial si la TLB comparara la ID del proceso además de la etiqueta al juzgar si se acierta o no! De esta forma, se pueden distinguir entradas TLB de diferentes procesos.

Aunque el proceso A y el proceso B tienen las mismas direcciones virtuales, pero los ID de proceso son diferentes, naturalmente, el proceso B no accederá a la entrada TLB del proceso A. Por lo tanto, la TLB agrega una coincidencia ASID (Address Space ID).

ASID es similar al ID de proceso, que se utiliza para distinguir las entradas TLB de diferentes procesos. De esta forma, no hay necesidad de vaciar el TLB cuando se cambia el proceso. Pero aún se requiere software para administrar y asignar ASID.

Cómo administrar los ASID

ASID y el ID de proceso definitivamente no son lo mismo, no los confunda. El ID de proceso puede tomar una amplia gama de valores. Pero ASID es generalmente de 8 o 16 bits. Entonces solo se pueden distinguir 256 o 65536 procesos. Nuestro ejemplo se ilustra con un ASID de 8 bits.

Por lo tanto, es imposible para nosotros tener una correspondencia uno a uno entre el ID del proceso y el ASID.Debemos asignar un ASID a cada proceso, y el ID del proceso y el ASID de cada proceso generalmente no son iguales.

Cada vez que se crea un nuevo proceso, se le asigna un nuevo ASID. Después de asignar el ASID, vacíe todos los TLB y reasigne el ASID.

Por lo tanto, si desea evitar la descarga de TLB por completo, idealmente, la cantidad de procesos en ejecución debe ser menor o igual a 256. Sin embargo, este no es el caso, por lo que se requiere una combinación de software y hardware para administrar los ASID.

Para gestionar cada proceso, el kernel de Linux contará con una estructura task_struct, donde podremos almacenar el ASID asignado al proceso actual. El registro de direcciones base de la tabla de páginas tiene bits libres que también se pueden usar para almacenar el ASID. Cuando se cambia el proceso, la dirección base de la tabla de páginas y el ASID (que se puede obtener de task_struct) se pueden almacenar juntos en el registro de direcciones base de la tabla de páginas.

Al buscar la TLB, el hardware puede comparar la etiqueta y el ASID para determinar si son iguales (comparar el ASID almacenado en el registro de dirección base de la tabla de páginas con el ASID almacenado en la entrada de la TLB). Si todos son iguales, significa TLB hit. De lo contrario, se perderá TLB. Cuando falla la TLB, es necesario atravesar la tabla de páginas en múltiples niveles para encontrar la dirección física. Luego se almacena en caché en el TLB y el ASID actual se almacena en caché al mismo tiempo.

compartida por múltiples procesos

Sabemos que el espacio del kernel y el espacio del usuario están separados, y todos los procesos comparten el espacio del kernel. Dado que el espacio del kernel es compartido, cuando el proceso A cambia al proceso B, si la dirección a la que accede el proceso B está en el espacio del kernel, se puede usar el TLB almacenado en caché por el proceso A. Pero ahora, debido a que el ASID es diferente, conduce a la falta de TLB.

Nuestro mapeo global compartido para el espacio del kernel se llama mapeo global. Las asignaciones para cada proceso se denominan asignaciones no globales.

Por lo tanto, introducimos un bit (bit no global (nG)) en el último nivel de la tabla de páginas para representar si se trata de un mapeo global. Cuando la relación de la dirección física del mapeo de direcciones virtuales se almacena en caché en el TLB, el bit nG también se almacena.

Cuando juzgue si debe acertar el TLB, cuando compare las etiquetas son iguales, luego juzgue si se trata de un mapeo global, si es así, juzgue directamente el acierto de TLB sin comparar el ASID. Cuando no es un mapeo global, el ASID finalmente se compara para determinar si el TLB acertó.

¿Cuándo se debe enjuagar el TLB?

Vayamos al resumen final, cuándo se debe vaciar TLB.

  • Cuando se asignan los ASID, es necesario vaciar todos los TLB. Los ASID se pueden administrar mediante mapas de bits, y todos los mapas de bits deben borrarse después de vaciar los TLB.
  • Cuando creamos un mapeo de tabla de páginas, necesitamos vaciar la entrada TLB correspondiente a la dirección virtual. La primera impresión puede ser que la TLB enrasada solo se requiere cuando se modifica la asignación de la tabla de páginas, pero la situación real es que la TLB enrasada es necesaria siempre que se establezca la asignación. La razón es que cuando crea un mapeo, no sabe si hubo un mapeo antes. Por ejemplo, si crea un mapeo desde la dirección virtual A a la dirección física B, no sabemos si hay un mapeo desde dirección virtual A a la dirección física C antes, por lo que se unifica en Flush TLB al establecer una relación de mapeo.

Autor del texto original: [ Learn Embedded Together

 

Supongo que te gusta

Origin blog.csdn.net/youzhangjing_/article/details/132088646
Recomendado
Clasificación