Los procesos no trabajan directamente con la memoria física, sino que lo hacen con la memoria virtual. Aplicaciones que realizan una gran cantidad de accesos a memoria pueden obtener mejoras de rendimiento usando páginas grandes gracias a la traducción reducida Lookaside Buffer (TLB). Hugetlbfs es una función de administración de memoria que se ofrece en el kernel de Linux, que es útil para aplicaciones que utilizan un gran espacio de direcciones virtuales.
Para ello se debe realizar una conversión, entre la memoria física y la virtual. Para dicha conversión cada proceso dispone de una tabla de conversión, y como lo que contiene son direcciones de pagina, se llama tabla de paginación. En aplicaciones con mucho consumo de memoria, donde además la información cambia constantemente (por ejemplo, una base de datos), el acceso a la tabla de paginación es constante.
Debido a esto existe la “Translation Lookaside Buffer”, una pequeña cache con parte de la tabla de paginación. El problema es que la TLB es de tamaño fijo, y como normalmente guardamos direcciones de páginas de 4 KBytes; el total de memoria al que nos da acceso la TLB no es muy grande. Con lo cual como consecuente tenemos esta situación :
Utilizar tamaños mayores de página o Hugepages (el caso más habitual 2 MBytes). Esto supone acceder a una mayor cantidad de memoria con las mismas entradas (PTE) en la tabla de paginación. Reduciendo así el consumo de CPU.
Ejecutar el siguiente comando:
$ grep -i huge /proc/meminfo
La salida debe ser similar a:
HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB
El núcleo compilado con hugepage debe mostrar el número de páginas gigantes configuradas en el sistema. De lo contrario, es necesario recompilar el kernel de Linux con la opción de CONFIG_HUGETLBFS habilitada.
Para mas información leer Manejo de memoria en Linux.
Detalles sobre su uso, especialmente con Oracle:
La característica de hugetlbfs permite a una aplicación a poder utilizar un tamaño de página mucho más grande de lo normal, de modo que una entrada de TLB solo puede asignar un mayor espacio de direcciones. Las entradas en HugeTLB pueden variar en tamaño. Por ejemplo, la arquitectura i386 soporta 4K y 4M (2M en modo PAE), tamaños de página, ia64 arquitectura soporta tamaños de varias páginas 4K, 8K,64K, 256K, 1M, 4M, 16M, 256M y ppc64 apoya 4K y 16M.
Para asignar hugepage, puede definir el número de páginas gigantes mediante la configuración de valor en /proc/sys/vm/nr_hugepages, escriba:
sysctl -w vm.nr_hugepages=40 (Puede hacerlo de manera mas manual, abriendo el archivo /etc/sysctl y agregando vm.nr_hugepages=40)
Hecho lo anterior actualizamos:
bash$ sysctl -p
Ahora a verificar si se configuraron las paginas:
bash# grep -i huge /proc/meminfo HugePages_Total: 40 HugePages_Free: 40 HugePages_Rsvd: 0 Hugepagesize: 2048 kB
Donde:
Un semáforo se puede pensar como un contador que se utiliza para acceder a los recursos compartidos del sistema.
Desde la linea de comandos se puede ver la memoria compartida y los semáforos usados
srvlxsid:~ # ipcs ------ Shared Memory Segments -------- key shmid owner perms bytes nattch status 0x52205704 32768 orasid 640 20487077888 375 0x00000000 65537 sidadm 777 1024 1 0x00004dbe 13074463 sidadm 777 574868 1 0x00002748 13140000 sidadm 740 534592 15 ------ Semaphore Arrays -------- key semid owner perms nsems 0xc1f65328 98304 orasid 640 1004 0x00004e62 3932277 sidadm 740 1 0x00004e28 3965046 sidadm 740 1 0x00004e68 3997815 sidadm 740 1 ------ Message Queues -------- key msqid owner perms used-bytes messages
ipcs -l ---- Límites memoria compartida ---- número máx. segmentos = 4096 tamaño máx. segmento (kbytes) = 9007199254740991 max total shared memory (kbytes) = 4611686018427386880 tamaño mín. segmento (bytes) = 1 ------ Límites semáforo -------- número máximo de matrices = 8192 máx. semáforos por matriz = 1250 máx. semáforos sistema = 256000 máx. oper. por llamada semop = 100 valor máx. semáforo = 32767 ------ Mensajes: límites ------- máx. colas sistema = 32768 tamaño máx. mensaje (bytes) = 65536 tamaño máx. predeterminado cola (bytes) = 65536
kernel.shmmax = 9223372036854775807 kernel.sem = 1250 256000 100 8192 kernel.shmall = 1152921504606846720 vm.max_map_count = 1000000 vm.nr_hugepages=12000
memlock : memoria compartida en kilobytes
* soft nofile 4096 * hard nofile 63536 * soft memlock 26214400 * hard memlock 26214400 @ejemplo - memlock unlimited
/etc/security/limits.conf Debe tener un valor asignado un poco menor a la memoria instalada, por ejemplo si tenemos 64GB of RAM, un valor apropiado puede ser :
soft memlock 60397977 hard memlock 60397977
Script que calcula automaticamente el valor de hugepages, usar solo como orientación
Oracle recomiendar calcular de esta forma :
ipcs -m
key | shmid | owner | perms | bytes |
---|---|---|---|---|
0x00004dc4 0x00004dbe 0x52205704 0x00000000 0x0382be84 0x00002749 0x0000271a 0x00002711 0x00002712 0x00002713 0x00002744 0x0000272f 0x00002743 0x0000274e 0x00002759 0x0000274f 0x0000271e 0x00002719 0x00002718 0x00002722 0x00002738 0x00002717 0x00002714 0x00002739 0x00002723 0x00002731 0x00002746 0x00002751 0x00002750 0x00002761 0x00002716 0x0000272e 0x00002732 0x0000274a 0x00002748 | 229376 262145 88670210 88702979 360452 88735749 92143622 92176391 92209160 92241929 92274698 92307467 92340236 92405773 95813646 99221519 99254288 99287057 99319826 99352595 99385364 99418133 99483670 99516439 99549208 99581977 99614746 99647515 99680284 99713053 101646366 101679135 101711904 101744673 101777442 | sapadm root orasid sidadm sidadm sidadm sidadm sidadm sidadm sidadm sidadm sidadm sidadm sidadm sidadm sidadm sidadm sidadm sidadm sidadm sidadm sidadm sidadm sidadm sidadm sidadm sidadm sidadm sidadm sidadm sidadm sidadm sidadm sidadm sidadm | 760 777 640 740 640 740 740 740 740 740 740 740 740 740 740 740 740 740 740 740 740 740 740 740 740 740 740 740 740 740 740 740 740 740 740 | 40141728 793440 47246737408 1024 4096 1639280 200000000 588 62456056 200592000 179368 6387876 23738964 86484792 60211232 86040 40000000 2147483648 2147483648 6423584 662000000 31072 645640 45454312 1799999904 92159912 287465496 33554456 4194456 19480 4096000000 126790 83394560 2076 535000 |
De la cantidad de bytes formamos una matriz que es la de segmentos de memoria compartida en bytes y realizamos el siguiente cálculo :
http://docs.oracle.com/cd/E37670_01/E37355/html/ol_config_hugepages.html
#!/bin/bash # # hugepages_settings.sh # # Linux bash script to compute values for the # recommended HugePages/HugeTLB configuration # # Note: This script does calculation for all shared memory # segments available when the script is run, no matter it # is an Oracle RDBMS shared memory segment or not. # Check for the kernel version KERN=`uname -r | awk -F. '{ printf("%d.%d\n",$1,$2); }'` # Find out the HugePage size HPG_SZ=`grep Hugepagesize /proc/meminfo | awk {'print $2'}` # Start from 1 pages to be on the safe side and guarantee 1 free HugePage NUM_PG=1 # Cumulative number of pages required to handle the running shared memory segments for SEG_BYTES in `ipcs -m | awk {'print $5'} | grep "[0-9][0-9]*"` do MIN_PG=`echo "$SEG_BYTES/($HPG_SZ*1024)" | bc -q` if [ $MIN_PG -gt 0 ]; then NUM_PG=`echo "$NUM_PG+$MIN_PG+1" | bc -q` fi done # Finish with results case $KERN in '2.4') HUGETLB_POOL=`echo "$NUM_PG*$HPG_SZ/1024" | bc -q`; echo "Recommended setting: vm.hugetlb_pool = $HUGETLB_POOL" ;; '2.6') echo "Recommended setting: vm.nr_hugepages = $NUM_PG" ;; *) echo "Unrecognized kernel version $KERN. Exiting." ;; esac # End
Con Oracle en el Kernel 3.0 es recomendable deshabilitar las páginas transparentes.
Podemos hacerlos on-the-fly
echo never > /sys/kernel/mm/transparent_hugepage/enabled
O al inicio del sistema desde la cmdline de booteo :
transparent_hugepage=never