Vantaxes e inconvenientes de HugePages

Vantaxes e inconvenientes de HugePages

Tradución do artigo elaborado para os alumnos do curso "Administrador Linux".

Anteriormente, falei sobre como probar e activar Hugepages en Linux.
Este artigo só será útil se realmente tes un lugar para usar Hugepages. Coñecín a moita xente que se deixa enganar coa perspectiva de que Hugepages mellorará a produtividade de xeito máxico. Non obstante, a enorme páxina é un tema complexo e pode degradar o rendemento se se usa incorrectamente.

Parte 1: verificar que as páxinas enormes estean activadas en Linux (orixinal aquí)

Problema:
Debes comprobar se HugePages está activado no teu sistema.

solución:
É ben sinxelo:

cat /sys/kernel/mm/transparent_hugepage/enabled

Recibirás algo así:

always [madvise] never

Verá unha lista de opcións dispoñibles (sempre, tolo, nunca), e a opción activa actualmente estará encerrada entre parénteses (por defecto tolo).

tolo significa iso transparent hugepages habilitado só para áreas de memoria que solicitan explícitamente páxinas enormes usando tolo (2).

sempre significa iso transparent hugepages sempre activado para todos os procesos. Isto xeralmente mellora o rendemento, pero se tes un caso de uso no que moitos procesos están a consumir unha pequena cantidade de memoria, entón a carga total de memoria pode aumentar drasticamente.

nin significa iso transparent hugepages non se incluirá nin sequera cando se solicite mediante madvise. Para saber máis, póñase en contacto documentación kernels de Linux.

Como cambiar o valor predeterminado

Opción 1: Cambia directamente sysfs (despois de reiniciar o parámetro volverá ao seu valor predeterminado):

echo always >/sys/kernel/mm/transparent_hugepage/enabled
echo madvise >/sys/kernel/mm/transparent_hugepage/enabled
echo never >/sys/kernel/mm/transparent_hugepage/enabled

Opción 2: Cambie a configuración predeterminada do sistema recompilando o núcleo cunha configuración modificada (esta opción só se recomenda se está a usar un núcleo personalizado):

  • Para configurar sempre por defecto, use:
    CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
    # Comment out CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y
  • Para configurar madvise como predeterminado, use:
    CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y
    # Comment out CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y

Parte 2: Vantaxes e inconvenientes de HugePages

Tentaremos explicar de forma selectiva as vantaxes, inconvenientes e posibles trampas do uso de Hugepages. Dado que un artigo tecnoloxicamente complexo e pedante probablemente será difícil de entender para as persoas que se enganan ao pensar que Hugepages é unha panacea, sacrificarei a precisión pola sinxeleza. Convén ter en conta que moitos dos temas son realmente complexos e, polo tanto, moi simplificados.

Teña en conta que estamos a falar de sistemas x64 de 86 bits que executan Linux, e que simplemente estou asumindo que o sistema admite páxinas enormes transparentes (xa que non é unha desvantaxe que as páxinas enormes non se sobrescriban), como é o caso de case calquera Linux moderno. ambiente.

Adxuntarei máis descrición técnica nos seguintes enlaces.

Memoria virtual

Se es un programador de C++, sabe que os obxectos na memoria teñen enderezos específicos (valores de punteiro).

Non obstante, estes enderezos non necesariamente reflicten enderezos físicos na memoria (enderezos RAM). Representan enderezos na memoria virtual. O procesador ten un módulo especial MMU (unidade de xestión de memoria) que axuda ao núcleo a asignar a memoria virtual a unha localización física.

Este método ten moitas vantaxes, pero as máis importantes son:

  • Rendemento (por varios motivos);
  • Illamento do programa, é dicir, ningún programa pode ler na memoria doutro programa.

Que son as páxinas?

A memoria virtual divídese en páxinas. Cada páxina individual apunta a unha memoria física específica, pode apuntar a unha área na RAM ou pode apuntar a un enderezo asignado a un dispositivo físico, como unha tarxeta de vídeo.

A maioría das páxinas coas que tratas apuntan á memoria RAM ou son intercambiadas, o que significa que están almacenadas no teu disco duro ou SSD. O núcleo xestiona o deseño físico de cada páxina. Se se accede a unha páxina falsificada, o núcleo detén o fío que está tentando acceder á memoria, le a páxina do disco duro/SSD á memoria RAM e, a continuación, continúa executando o fío.

Este proceso é transparente, o que significa que non necesariamente se le directamente desde o HDD/SSD. O tamaño das páxinas normais é de 4096 bytes. O tamaño das páxinas enormes é de 2 megabytes.

Buffer asociativo de tradución (TLB)

Cando un programa accede a unha páxina de memoria, a CPU debe saber de que páxina física debe ler os datos (é dicir, ter un mapa de enderezos virtual).

O núcleo ten unha estrutura de datos (táboa de páxinas) que contén toda a información sobre as páxinas que se utilizan. Usando esta estrutura de datos, pode asignar un enderezo virtual a un enderezo físico.

Non obstante, a táboa de páxinas é bastante complexa e lenta, polo que simplemente non podemos analizar toda a estrutura de datos cada vez que un proceso accede á memoria.

Afortunadamente, o noso procesador ten un TLB que almacena en caché a asignación entre enderezos virtuais e físicos. Isto significa que aínda que necesitamos analizar a táboa de páxinas no primeiro intento de acceso, todos os accesos posteriores á páxina pódense xestionar no TLB, o que permite un funcionamento rápido.

Debido a que está implementado como un dispositivo físico (o que o fai rápido en primeiro lugar), a súa capacidade é limitada. Polo tanto, se queres acceder a máis páxinas, o TLB non poderá almacenar as asignacións de todas elas, polo que o teu programa funcionará moito máis lento.

Hugepages vén ao rescate

Entón, que podemos facer para evitar o desbordamento de TLB? (Supoñemos que o programa aínda necesita a mesma cantidade de memoria).

Aquí é onde entra Hugepages. En lugar de 4096 bytes que requiren só unha entrada TLB, unha entrada TLB agora pode apuntar a 2 megabytes. Supoñamos que o TLB ten 512 entradas, aquí sen Hugepages podemos igualar:

4096 b⋅512=2 MB

Entón, como podemos comparar con eles:

2 MB⋅512=1 GB

É por iso que Hugepages é incrible. Poden mellorar a produtividade sen moito esforzo. Pero aquí hai advertencias importantes.

Suplantación de páxinas enormes

O núcleo supervisa automaticamente a frecuencia con que se usa cada páxina de memoria. Se non hai memoria física (RAM) suficiente, o núcleo moverá páxinas menos importantes (utilizadas con menos frecuencia) ao disco duro para liberar algo de RAM para páxinas máis importantes.
En principio, o mesmo aplícase a Hugepages. Non obstante, o núcleo só pode intercambiar páxinas enteiras, non bytes individuais.

Digamos que temos un programa coma este:

char* mymemory = malloc(2*1024*1024); // Возьмем это за одну Hugepage!
// Заполним mymemory какими-либо данными
// Сделаем много других вещей,
// которые приведут к подмене страницы mymemory
// ...
// Запросим доступ только к первому байту
putchar(mymemory[0]); 

Neste caso, o núcleo terá que substituír (ler) ata 2 megabytes de información do disco duro/SSD só para que poidas ler un byte. En canto ás páxinas normais, só hai que ler 4096 bytes do disco duro/SSD.

Polo tanto, se se anula hugepage, só é máis rápido de ler se precisas acceder a toda a páxina. Isto significa que se estás tentando acceder aleatoriamente a diferentes partes da memoria e só estás lendo un par de kilobytes, debes usar páxinas normais e non preocuparte por nada máis.

Por outra banda, se precisa acceder a unha gran parte da memoria secuencialmente, as páxinas enormes mellorarán o seu rendemento. Non obstante, cómpre probalo vostede mesmo (non con software abstracto) e ver o que funciona máis rápido.

Asignación en memoria

Se escribe C, sabe que pode solicitar cantidades arbitrariamente pequenas (ou case arbitrariamente grandes) de memoria do montón usando malloc(). Digamos que necesitas 30 bytes de memoria:

char* mymemory = malloc(30);

Para un programador, pode parecer que estás "solicitando" 30 bytes de memoria do sistema operativo e devolvendo un punteiro a algunha memoria virtual. Pero en realidade malloc () é só unha función C que chama desde dentro da función brk e sbrk para solicitar ou liberar memoria do sistema operativo.

Non obstante, solicitar cada vez máis memoria para cada asignación é ineficiente; o máis probable é que algún segmento de memoria xa foi liberado (free()), e podemos reutilizalo. malloc() implementa algoritmos bastante complexos para reutilizar a memoria liberada.

Ao mesmo tempo, todo pasa desapercibido para ti, entón por que debería preocuparte? Pero porque o reto free() non quere dicir iso a memoria devólvese necesariamente inmediatamente ao sistema operativo.

Hai algo como a fragmentación da memoria. En casos extremos, hai segmentos de montón nos que só se usan uns poucos bytes mentres se libera todo o que está no medio (free()).

Teña en conta que a fragmentación da memoria é un tema incriblemente complexo, e incluso cambios menores nun programa poden ter un impacto significativo. Na maioría dos casos, os programas non provocarán unha fragmentación significativa da memoria, pero debes ter en conta que se hai un problema coa fragmentación nalgunha área do montón, as páxinas enormes poden empeorar a situación.

Uso selectivo de páxinas grandes

Despois de ler este artigo, determinou que partes do seu programa poden beneficiarse de usar hugepages e cales non. Entón, debería habilitarse as enormes páxinas?

Por sorte podes usar madvise()para habilitar a enorme páxina só para aquelas áreas de memoria onde sería útil.

Primeiro, verifique que hugepages estea executando no modo madvise() usando instrucións ao comezo do artigo.

Despois, usa madvise()para dicirlle ao núcleo exactamente onde usar as páxinas enormes.

#include <sys/mman.h>
// Аллоцируйте большое количество памяти, которую будете использовать
size_t size = 256*1024*1024;
char* mymemory = malloc(size);
// Просто включите hugepages…
madvise(mymemory, size, MADV_HUGEPAGE);
// … и задайте следующее
madvise(mymemory, size, MADV_HUGEPAGE | MADV_SEQUENTIAL)

Teña en conta que este método é simplemente un consello para o núcleo sobre como xestionar a memoria. Isto non significa que o núcleo use automaticamente páxinas enormes para unha memoria determinada.

Consulta a documentación (páxina de manual)consellopara saber máis sobre a xestión da memoria e madvise(), este tema ten unha curva de aprendizaxe incriblemente pronunciada. Entón, se pretendes ser moi bo, prepárate para ler e probar durante unhas semanas antes de esperar resultados positivos.

Que ler?

Tes algunha pregunta? Escribe nos comentarios!

Fonte: www.habr.com

Engadir un comentario