2010-05-20 12 views
18

Las CPU modernas x86 tienen la capacidad de admitir tamaños de página más grandes que el 4K heredado (es decir, 2 MB o 4 MB), y hay instalaciones de SO (Linux, Windows) para acceder a esta funcionalidad.¿En qué circunstancias pueden las páginas grandes producir una aceleración?

El enlace de Microsoft anterior indica que las páginas grandes "aumentan la eficacia del búfer de traducción, lo que puede aumentar el rendimiento de la memoria a la que se accede con frecuencia". Lo cual no es muy útil para predecir si las páginas grandes mejorarán cualquier situación dada. Me interesan los ejemplos concretos, preferiblemente cuantificados, de cómo mover la lógica de un programa (o una aplicación completa) para usar páginas enormes ha resultado en una mejora en el rendimiento. ¿Alguien tiene alguna historia de éxito?

Hay un caso particular, no conozco myself: la utilización de grandes páginas pueden dramatically reducir el tiempo necesario para desembolsar un proceso de gran tamaño (presumiblemente como el número de registros de la TLB que necesitan la copia se reduce por un factor del orden de 1000). Me interesa saber si las páginas grandes también pueden ser beneficiosas en escenarios menos exóticos.

Respuesta

10

Intenté idear algún código que maximizara la manipulación del TLB con 4k páginas para examinar las ganancias posibles de páginas grandes. Lo siguiente a continuación ejecuta 2.6 veces más rápido (que páginas 4K) cuando las páginas de 2MByte son proporcionadas por malloc de libhugetlbfs (Intel i7, Debian Lenny de 64 bits); esperemos que sea obvio lo que scoped_timer y random0n hacen.

volatile char force_result; 

    const size_t mb=512; 
    const size_t stride=4096; 
    std::vector<char> src(mb<<20,0xff); 
    std::vector<size_t> idx; 
    for (size_t i=0;i<src.size();i+=stride) idx.push_back(i); 
    random0n r0n(/*seed=*/23); 
    std::random_shuffle(idx.begin(),idx.end(),r0n); 

    { 
    scoped_timer t 
     ("TLB thrash random",mb/static_cast<float>(stride),"MegaAccess"); 
    char hash=0; 
    for (size_t i=0;i<idx.size();++i) 
     hash=(hash^src[idx[i]]); 
    force_result=hash; 
    } 

Una versión más simple "línea recta" con sólo hash=hash^src[i] sólo ganó el 16% de las grandes páginas, pero (especulación) de Intel fancy prefetching hardware puede estar ayudando el caso 4K cuando los accesos son predecibles (supongo que podría disable prefetching para investigar si eso es cierto).

+2

La recuperación previa de hardware no cruzará 4k límites de página, pero lo que probablemente esté viendo en el caso de línea recta es que los accesos a la tabla de página son muy predecibles, por lo que el recorrido de página que ocurre cuando falla en el TLB están todos en L1 (estas entradas de la página pueden haberse ingresado a través de la captación previa). – BeeOnRope

3

He visto mejoras en algunos escenarios de HPC/Grid, específicamente paquetes de física con modelos muy, muy grandes en máquinas con mucha y mucha RAM. Además, el proceso que ejecutaba el modelo era lo único activo en la máquina. Sospecho, aunque no he medido, que ciertas funciones de BD (por ejemplo, importaciones masivas) se beneficiarían también.

Personalmente, creo que a menos que tenga un perfil de acceso a la memoria muy perfilado y que tenga acceso a una gran cantidad de memoria, es poco probable que vea una mejora significativa.

2

Obtengo un ~ 5% de aceleración en servidores con mucha memoria (> = 64 GB) ejecutando procesos grandes. p. para un proceso de 16 GB de Java, eso es 4M x 4kB páginas pero solo 4k x 4MB páginas.

14

La mayor diferencia en el rendimiento vendrá cuando realice accesos aleatorios ampliamente espaciados a una gran región de memoria, donde "grande" significa mucho más grande que el rango que puede ser mapeado por todas las entradas de página pequeña en el TLB (que generalmente tienen múltiples niveles en procesadores modernos).

Para hacer las cosas más complejas, el número de entradas TLB para páginas de 4kB suele ser mayor que el número de entradas para páginas de 2MB, pero esto varía mucho según el procesador. También hay una gran variación en la cantidad de entradas de "página grande" disponibles en el Nivel 2 TLB.

Por ejemplo, en una 10h Revisión AMD Opteron familia D ("Istanbul") del sistema, informes CPUID:

  • L1 DTLB: páginas de 4 KB: 48 entradas; 2MB páginas: 48 entradas; Páginas de 1GB: 48 entradas
  • L2 TLB: 4kB páginas: 512 entradas; 2MB páginas: 128 entradas; páginas 1 GB: 16 entradas

Mientras que en un sistema Intel Xeon 56xx ("Westmere"), informes CPUID:

  • L1 DTLB: páginas de 4 KB: 64 entradas; 2MB páginas: 32 entradas
  • L2 TLB: 4kB páginas: 512 entradas; páginas 2 MB: ninguno

ambos pueden asignar 2 MB (512 * 4kB) usando pequeñas páginas antes de sufrir el nivel 2 TLB, mientras que el sistema de Westmere puede mapear 64MB usando sus 32 entradas 2MB TLB y el sistema de AMD puede mapear 352MB utilizando las 176 entradas de 2MB TLB en sus TLB L1 y L2. Cualquiera de los sistemas obtendrá una aceleración significativa mediante el uso de páginas grandes para accesos aleatorios sobre rangos de memoria que son mucho más grandes que 2MB y menos de 64MB. El sistema AMD debe continuar mostrando un buen rendimiento usando páginas grandes para rangos de memoria mucho más grandes.

Lo que está tratando de evitar en todos estos casos es el peor de los casos (nota 1) escenario de atravesar los cuatro niveles de la traducción de dirección jerárquica x86_64.
Si ninguno de los mecanismos de caché de traducción de direcciones (nota 2) de trabajo, se requiere:

  • 5 viajes a la memoria para cargar datos mapeados en una página de 4 KB,
  • 4 viajes a la memoria para cargar datos mapeados en una página de 2 MB, y
  • 3 disparos a la memoria para cargar los datos mapeados en una página de 1GB.

En cada caso, el último viaje a la memoria es para obtener los datos solicitados, mientras que los otros viajes son necesarios para obtener las diversas partes de la información de traducción de la página. La mejor descripción que he visto es en la Sección 5.3 de AMD "Manual Volumen 2 de Arquitectura AMD64 Programador: Programación del sistema" (publicación 24593) http://support.amd.com/us/Embedded_TechDocs/24593.pdf

Nota 1: Las cifras anteriores no son realmente el caso peor. Correr bajo una máquina virtual empeora estos números. Al ejecutarse en un entorno que provoca que la memoria que contiene los distintos niveles de las tablas de páginas se intercambie al disco, el rendimiento es mucho mayor peor.

Nota 2: Desafortunadamente, incluso conocer este nivel de detalle no es suficiente, ya que todos los procesadores modernos tienen cachés adicionales para los niveles superiores de la jerarquía de traducción de páginas. Por lo que puedo decir, estos están muy mal documentados en público.

3

Esto se está volviendo esotérico, pero las páginas TLB enormes marcan una diferencia significativa en la arquitectura Intel Xeon Phi (MIC) cuando se realizan transferencias de memoria DMA (de Host a Phi mediante PCIe). This Intel link describes how to enable huge pages. Descubrí que el aumento de los tamaños de transferencia de DMA más allá de 8 MB con el tamaño de página TLB normal (4K) comenzó a disminuir el rendimiento, de aproximadamente 3 GB/s a ​​menos de 1 GB/s una vez que el tamaño de transferencia alcanza los 512 MB.

Después de habilitar grandes páginas TLB (2MB), la velocidad de datos continuó aumentando a más de 5 GB/s para las transferencias DMA de 512 MB.

Cuestiones relacionadas