Hacer que el intercambio de lectura de Linux vuelva a la memoria

28

El kernel de Linux intercambia la mayoría de las páginas de la memoria cuando ejecuto una aplicación que usa la mayoría de los 16 GB de memoria física. Una vez que finaliza la aplicación, cada acción (escribir comandos, cambiar áreas de trabajo, abrir una nueva página web, etc.) tarda mucho en completarse porque las páginas relevantes primero deben volver a leerse desde el intercambio.

¿Hay alguna manera de decirle al kernel de Linux que copie páginas del intercambio en la memoria física sin tocar manualmente (y esperar) cada aplicación? Ejecuto muchas aplicaciones, por lo que la espera siempre es dolorosa.

A menudo uso swapoff -a && swapon -apara hacer que el sistema responda nuevamente, pero esto borra las páginas del intercambio, por lo que deben escribirse nuevamente la próxima vez que ejecute el script.

¿Existe una interfaz de kernel, tal vez usando sysfs, para indicar al kernel que lea todas las páginas del intercambio?

Editar: De hecho, estoy buscando una manera de hacer que todos los intercambios se intercambien en caché. (¡Gracias, Derobert!)

[PS serverfault.com/questions/153946/… y serverfault.com/questions/100448/… son temas relacionados, pero no abordan la cuestión de cómo hacer que el kernel de Linux copie páginas del intercambio de nuevo en la memoria sin borrar el intercambio.]

drrossum
fuente
¿Desea que todo el intercambio sea un caché de la memoria del sistema? Entonces, ¿desea una imagen de la memoria del sistema que pueda recargar a voluntad? Así es básicamente cómo funciona la hibernación: el sistema captura su memoria en el disco, se apaga y restaura la imagen en el encendido. ¿Hay alguna posibilidad, cree usted, de que en una consulta que siga ese hilo pueda serle útil? Por ejemplo, si tuviera que crear una imagen en su memoria, deshabilitar el intercambio, completar una tarea, luego restaurar la imagen y repetir, ¿es eso algo que le gustaría hacer?
mikeserv
No creo que esto deje el intercambio en un estado intercambiado. Como tal, me parece que su sugerencia es una alternativa para el método swapoff-swapon.
drrossum
No, no almacena en caché el intercambio (que, ciertamente, es un poco extraño para mí) almacena en caché la RAM en algún momento que considere más integral, luego dedica toda la memoria del sistema a alguna tarea intensiva antes de restaurar la memoria caché cuando el La tarea ha terminado. Si desea intercambiar durante la tarea intensiva, entonces solo reducirá la velocidad de dicha tarea; necesitará tiempo adicional para intercambiar las páginas a medida que avanza.
mikeserv

Respuestas:

4

Basado en el programa memdump originalmente encontrado aquí , he creado un script para leer selectivamente las aplicaciones especificadas nuevamente en la memoria. remember:

#!/bin/bash
declare -A Q
for i in "$@"; do
    E=$(readlink /proc/$i/exe);
    if [ -z "$E" ]; then.
        #echo skipped $i;.
        continue;.
    fi
    if echo $E | grep -qF memdump; then.
        #echo skipped $i >&2;.
        continue;.
    fi
    if [ -n "${Q[${E}]}" ]; then.
        #echo already $i >&2;.
        continue;.
    fi
    echo "$i $E" >&2
    memdump $i 2> /dev/null
    Q[$E]=$i
done | pv -c -i 2 > /dev/null

Uso: algo como

# ./remember $(< /mnt/cgroup/tasks )
1 /sbin/init
882 /bin/bash
1301 /usr/bin/hexchat
...
2.21GiB 0:00:02 [ 1.1GiB/s] [  <=>     ]
...
6838 /sbin/agetty
11.6GiB 0:00:10 [1.16GiB/s] [      <=> ]
...
23.7GiB 0:00:38 [ 637MiB/s] [   <=>    ]
# 

Salta rápidamente sobre la memoria no intercambiada (gigabytes por segundo) y se ralentiza cuando se necesita el intercambio.

Vi.
fuente
Esta herramienta hace exactamente lo que estaba buscando. ¡Gracias!
drrossum
Una cosa buena es que, desde mi observación, las páginas intercambiadas se copian en la RAM, pero no se eliminan del intercambio (al menos, la mayoría de ellas no, porque el uso del intercambio solo disminuye ligeramente). Mi interpretación es que Linux mantiene dos copias de cada página, una en RAM y otra en el intercambio. Si esto se maneja correctamente, es incluso mejor que cancelar y agregar el intercambio nuevamente, porque significa que, cuando una página doble tendrá que intercambiarse nuevamente, no habrá necesidad de otra copia. Gracias a cualquier experto en kernel que pueda confirmar.
Giovanni Mascellani
11

Podría ayudar a subir /proc/sys/vm/page-cluster(por defecto: 3).

De la documentación del núcleo ( sysctl/vm.txt):

grupo de páginas

Page-cluster controla el número de páginas hasta las cuales se leen páginas consecutivas desde el intercambio en un solo intento. Esta es la contraparte de intercambio de lectura de caché de página. La consecutividad mencionada no es en términos de direcciones virtuales / físicas, sino consecutivas en el espacio de intercambio, lo que significa que se intercambiaron juntas.

Es un valor logarítmico: establecerlo en cero significa "1 página", establecerlo en 1 significa "2 páginas", establecerlo en 2 significa "4 páginas", etc. Cero desactiva completamente la lectura de intercambio.

El valor predeterminado es tres (ocho páginas a la vez). Puede haber algunos pequeños beneficios al ajustar esto a un valor diferente si su carga de trabajo requiere un intercambio intensivo.

Los valores más bajos significan latencias más bajas para las fallas iniciales, pero al mismo tiempo fallas adicionales y demoras de E / S para las fallas siguientes si hubieran sido parte de las páginas consecutivas que habría introducido la lectura anticipada.

La documentación no menciona un límite, por lo que posiblemente podría establecer este nivel absurdamente alto para que todo el intercambio se lea de nuevo muy pronto. Y, por supuesto, volver a un valor razonable después.

derobert
fuente
Esto suena como una solución útil. Las dos intervenciones manuales podrían combinarse con un comando de suspensión para que sea una intervención de un solo usuario. Pero, no necesariamente puede hacer que todos los intercambios se intercambien rápidamente, ya que solo se lee consecutivamente desde la página a la que se accede. Sin embargo, es la mejor solución hasta ahora. ¡Gracias!
drrossum
tbh esta es probablemente la mejor solución que vas a obtener. No he oído hablar de él antes, pero parece que convierte el intercambio en una serie de IOP grandes en lugar de un conjunto continuo de IOP pequeños, que probablemente sea lo que está causando sus problemas de rendimiento. Me sorprendería legítimamente si hubiera algo que abordara perfectamente su situación individual.
Bratchley
Para el caso, si experimenta ralentizaciones debido a muchos pequeños intercambios consecutivos, incluso el ajuste permanente del page-clustervalor puede mejorar el rendimiento.
Ilmari Karonen
5

Puede intentar agregar los programas que más le interesan a un cgroup y ajustar el intercambio para que la próxima vez que la aplicación ejecute los programas que agregue sean menos propensos a ser candidatos para el intercambio.

Es probable que algunas de sus páginas aún se intercambien, pero puede solucionar sus problemas de rendimiento. Una gran parte de esto es probablemente el comportamiento de "detener y comenzar" cuando muchas páginas de un programa están en intercambio y el programa tiene que pausar continuamente para intercambiar sus páginas en RAM, pero solo en incrementos de 4k.

Alternativamente, puede agregar la aplicación que se está ejecutando a un cgroup y ajustar el intercambio para que la aplicación sea la que más utilice el archivo de intercambio. Disminuirá la velocidad de la aplicación pero ahorrará el resto del sistema.

Bratchley
fuente
4

Me parece que no puedes mágicamente "hacer que el sistema responda de nuevo". O incurres en la penalización o lees páginas desde el espacio de intercambio a la memoria ahora o incurres más tarde, pero de una forma u otra incurres en ella. De hecho, si hace algo así swapoff -a && swapon -a, puede sentir más dolor en lugar de menos, porque obliga a que algunas páginas se vuelvan a copiar en la memoria que de otra manera nunca hubieran sido necesarias y finalmente se caigan sin ser leídas (piense: abandona una aplicación mientras gran parte de su montón se intercambia; esas páginas se pueden descartar por completo sin tener que volver a leerlas en la memoria).

pero esto borra las páginas del intercambio, por lo que deben escribirse nuevamente la próxima vez que ejecute el script.

Bueno, casi todas las páginas que se copian desde el intercambio a la memoria principal están a punto de modificarse de todos modos, por lo que si alguna vez fuera necesario volver a cambiar para intercambiar en el futuro, de todos modos tendría que escribirse nuevamente en el intercambio. Tenga en cuenta que el intercambio es principalmente memoria de almacenamiento dinámico, no páginas de solo lectura (que generalmente están respaldadas por archivos).

Creo que tu swapoff -a && swapon -atruco es tan bueno como cualquier cosa que se te ocurra .

Celada
fuente
Esos dos de nosotros estamos diciendo exactamente lo mismo al mismo tiempo;)
Ricitos
@goldilocks sí, vi su respuesta aparece antes que la mía estaba lista, pero yo ya estaba ¾ de hecho hasta que me quedé con él :-)
Celada
usted y goldilocks dicen lo mismo, pero no creo que así sea cómo funciona el almacenamiento en caché de intercambio. Tengo entendido que puede tener páginas en intercambio Y memoria al mismo tiempo. La página de intercambio solo se invalida una vez que se actualiza la página en la memoria.
drrossum
Confío en que la respuesta a la que se refirió David Spillett es correcta: de hecho, puede tener una página en intercambio y RAM al mismo tiempo ... pero solo hasta que se modifique la versión de RAM. Luego debe descartar la copia desactualizada en el intercambio. Cuando dije "casi todas las páginas que se vuelven a copiar del intercambio [...] están a punto de modificarse de todos modos", lo que quiero decir es que espero que esto sea lo que sucede la mayor parte del tiempo, así que no espero páginas en ambos lugares es una fracción significativa por la que vale la pena preocuparse.
Celada
Su escenario de uso puede ser diferente: puede tener muchas aplicaciones con grandes cantidades que con frecuencia se leen y no se escriben. Mi sensación es que la mayoría de la gente no tiene ese escenario. Pero si lo haces, supongo que tienes razón: swapoff -a && swapon -ano será bueno para ti. Supongo que en ese caso necesitaría algo que escanee /proc/<each-process>/memy lea cada página de memoria para asegurarse de que exista en la RAM. No sé si eso existe.
Celada
0

Hay una muy buena discusión aquí http://rudd-o.com/en/linux-and-free-software/tales-from-responsivenessland-why-linux-feels-slow-and-how-to-fix-that lo que se reduce a la disminución del intercambio, con la idea de que para aumentar la capacidad de respuesta percibida del sistema, uno debe evitar el intercambio del código (y esto es lo que sucede). Esto no es realmente una respuesta a su pregunta, pero puede evitar que aparezca el problema (sus aplicaciones simplemente no se intercambian, solo datos no utilizados y caché de páginas)

Fedxa
fuente
Si bien esto puede responder teóricamente la pregunta, sería preferible incluir aquí las partes esenciales de la respuesta y proporcionar el enlace para referencia.
slm