
Tradución do artigo elaborado para os alumnos do curso .
Anteriormente falei sobre como comprobar e activar o uso de Hugepages en Linux.
Este artigo só che resultará útil se realmente tes un caso de uso para Hugepages. Atopei moita xente que se deixa enganar pola promesa de que Hugepages mellorará o rendemento por arte de maxia. Non obstante, o uso de hugepages é un tema complexo e, se se usa incorrectamente, pode degradar o rendemento.
Parte 1: Comprobar que as páxinas enormes estean activadas Linux (orixinal )
Problema:
Debes comprobar se HugePages está activado no teu sistema.
solución:
É bastante sinxelo:
cat /sys/kernel/mm/transparent_hugepage/enabledObterás algo así:
always [madvise] neverVerás unha lista de opcións dispoñibles (sempre, tolo, nunca), mentres que a opción activa actualmente estará entre corchetes (por defecto madvise).
madvise significa iso transparent hugepages activado só para áreas de memoria que solicitan explicitamente páxinas enormes usando .
sempre significa iso transparent hugepages Activado en todo momento e para todos os procesos. Isto normalmente mellora o rendemento, pero se tes un caso de uso no que moitos procesos consumen unha pequena cantidade de memoria, a carga xeral da memoria pode aumentar drasticamente.
nin significa iso transparent hugepages non se incluirá mesmo cando se solicite mediante madvise. Para obter máis información, consulte núcleos Linux.
Como cambiar o valor predeterminado
Opción 1: Cambiar 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/enabledOpción 2Cambia a configuración predeterminada do sistema recompilando o kernel coa configuración modificada (esta opción só se recomenda se estás a usar un kernel personalizado):
- Para definir sempre como predeterminado, use:
CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y # Comment out CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y - Para definir madvise como predeterminado, use:
CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y # Comment out CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y
Parte 2: Vantaxes e desvantaxes de HugePages
Tentaremos explicar selectivamente as vantaxes, desvantaxes e posibles inconvenientes de usar Hugepages. Dado que un artigo tecnoloxicamente complexo e pedante probablemente será difícil de entender para aqueles que se enganan e pensan que Hugepages é unha panacea, sacrificarei a precisión pola simplicidade. Convén ter en conta que moitos temas son realmente complexos e, polo tanto, moi simplificados.
Teña en conta que estamos a falar de sistemas x86 de 64 bits que funcionan con Linux, e que simplemente estou a supoñer que o sistema admite páxinas enormes transparentes (xa que non é unha desvantaxe que as páxinas enormes non sexan substituídas), como ocorre en case calquera entorno moderno Linux.
Adxunto máis descricións técnicas nas ligazóns de embaixo.
memoria virtual
Se es programador en C++, sabes que os obxectos da memoria teñen enderezos específicos (valores de punteiro).
Non obstante, estes enderezos non reflicten necesariamente enderezos de memoria física (enderezos RAM). Representan enderezos de memoria virtual. O procesador ten un módulo especial, a MMU (unidade de xestión de memoria), que axuda ao núcleo a mapear a memoria virtual a localizacións físicas.
Este enfoque ten moitas vantaxes, pero as máis importantes son:
- Produtividade (por diversas razóns);
- Illamento de programas, o que significa que ningún programa pode ler da memoria doutro programa.
Que son as páxinas?
A memoria virtual divídese en páxinas. Cada páxina individual apunta a unha localización específica da memoria física, que pode ser unha localización na RAM ou un enderezo asignado a un dispositivo físico, como unha tarxeta gráfica.
A maioría das páxinas coas que interactúas apuntan á RAM ou están intercambiadas, o que significa que se almacenan nun disco duro ou SSD. O kernel xestiona a localización física de cada páxina. Se se accede a unha páxina intercambiada, o kernel detén o fío que intenta acceder á memoria, le a páxina do disco duro/SSD na RAM e logo continúa a execución do fío.
Este proceso é transparente aos fíos, o que significa que non lee necesariamente directamente do disco duro/SSD. As páxinas normais teñen un tamaño de 4096 bytes. As páxinas enormes teñen un tamaño de 2 megabytes.
Búfer de tradución Lookaside (TLB)
Cando un programa accede a unha páxina de memoria, a CPU debe saber de que páxina física ler os datos (é dicir, debe ter un mapa de enderezos virtual).
O núcleo ten unha estrutura de datos (a táboa de páxinas) que contén toda a información sobre as páxinas en uso. Esta estrutura de datos permite mapear 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 na caché a correspondencia entre os enderezos virtuais e físicos. Isto significa que, aínda que precisamos analizar a táboa de páxinas para o primeiro intento de acceso, todos os accesos posteriores ás páxinas poden procesarse no TLB, o que garante 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 mapeamentos para todas elas, o que fará que o teu programa se execute 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 entran as Hugepages. En lugar de 4096 bytes que requiren só unha entrada TLB, unha única entrada TLB agora pode apuntar a uns asombrosos 2 megabytes. Supondo un TLB con 512 entradas, sen Hugepages, podemos mapear:
4096 b⋅512=2 MBEntón, como podemos comparalos con:
2 MB⋅512=1 GBPor iso as páxinas enormes son tan xeniais. Poden aumentar a produtividade sen moito esforzo. Pero hai algunhas advertencias importantes.
Substitución de Hugepages
O núcleo monitoriza automaticamente a frecuencia coa que se usa cada páxina de memoria. Se a memoria física (RAM) é insuficiente, o núcleo moverá as páxinas menos importantes (usadas con menos frecuencia) ao disco duro para liberar 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.
Supoñamos que temos un programa coma este:
char* mymemory = malloc(2*1024*1024); // Возьмем это за одну Hugepage!
// Заполним mymemory какими-либо данными
// Сделаем много других вещей,
// которые приведут к подмене страницы mymemory
// ...
// Запросим доступ только к первому байту
putchar(mymemory[0]); Neste caso, o núcleo tería que intercambiar (ler) 2 megabytes de información do disco duro/SSD só para que vostede lea un byte. Para as páxinas normais, só se precisan ler 4096 bytes do disco duro/SSD.
Polo tanto, se se intercambia hugepage, a súa lectura só é máis rápida se se precisa acceder á páxina completa. Isto significa que se se accede aleatoriamente a diferentes partes da memoria e só se len uns poucos kilobytes, deberían usar páxinas normais e non preocuparse 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, terá que probalo vostede mesmo (non con software abstracto) e ver cal funciona máis rápido.
Asignación de memoria
Se escribes C, sabes que podes solicitar cantidades de memoria arbitrariamente pequenas (ou case arbitrariamente grandes) do heap usando malloc()Digamos que necesitas 30 bytes de memoria:
char* mymemory = malloc(30);Para un programador, pode parecer que estás a "solicitar" 30 bytes de memoria ao sistema operativo e a devolver un punteiro a unha memoria virtual. Pero en realidade, malloc () — é só unha función C que chama funcións desde dentro 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 xa se liberase algún segmento de memoria. (free()), e podemos reutilizalo. malloc() implementa algoritmos bastante complexos para reutilizar a memoria liberada.
E, con todo, para ti, todo ocorre desapercibido, entón por que debería molestarte? Porque o desafío free() non significa que .
Existe un concepto chamado fragmentación da memoria. En casos extremos, hai segmentos de memoria dinámica onde só se usan uns poucos bytes, mentres que todo o que hai entre eles foi liberado. (free()).
Ten en conta que a fragmentación da memoria é un tema incriblemente complexo e que mesmo pequenos cambios nun programa poden afectalo significativamente. Na maioría dos casos, os programas non causan unha fragmentación significativa da memoria, pero debes ter en conta que se a fragmentación é un problema nunha área específica do montón de datos, as páxinas enormes só poden empeorar as cousas.
Uso selectivo de páxinas enormes
Despois de ler este artigo, xa determinaches que partes do teu programa poden beneficiarse das páxinas enormes e cales non. Entón, deberías activar as páxinas enormes?
Por sorte, podes usar madvise()para habilitar a paginación masiva só para aquelas áreas de memoria onde será útil.
Primeiro, comproba que hugepages se está a executar en modo madvise() usando ao comezo do artigo.
Entón, usa madvise()para indicarlle ao kernel exactamente onde usar 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)Ten en conta que este método é simplemente unha recomendación de xestión de memoria para o kernel. Non significa que o kernel empregue automaticamente páxinas enormes para a memoria dada.
Consulte a documentación para aprender máis sobre a xestión da memoria e madvise()Este tema ten unha curva de aprendizaxe incriblemente pronunciada. Polo tanto, se queres familiarizarte con el de verdade, prepárate para ler e probar durante varias semanas antes de esperar resultados positivos.
Que ler?
Tes algunha pregunta? Deixa un comentario!
Fonte: www.habr.com
