He estado probando diferentes métodos para mejorar el tiempo que lleva compilar todo mi proyecto de c ++. Actualmente lleva unos 5 minutos. Experimenté con distcc, ccache y otros. Recientemente, descubrí que si copio todo mi proyecto en una unidad RAM y luego compilo desde allí, reduce el tiempo de compilación al 30% de su original, solo 1.5 minutos.
Obviamente, trabajar desde la unidad de RAM no es práctico. Entonces, ¿alguien sabe de alguna manera en que puedo forzar al sistema operativo a mantener siempre un determinado directorio en caché ? Todavía quiero que el directorio se sincronice de nuevo en el disco de manera normal, pero siempre quiero una copia de los datos en la memoria también. es posible?
EDITAR:
Como una posible solución, solo pensamos en lanzar un demonio que se ejecuta rsync
cada 10 segundos más o menos para sincronizar la unidad de disco con una unidad de RAM. Luego ejecutamos la compilación desde la unidad RAM. El rsync
es increíblemente rápido, pero ¿funcionaría realmente? Seguramente el sistema operativo podría hacerlo mejor ...
fuente
time
tu compilación y compartir el resultado con nosotros? Disiparía alguna controversia creciente.make clean && /usr/bin/time -v make
(no use eltime
comando incorporado bash )time
bash incorporado (help time
) tiene muchos menos detalles (sin opción detallada) que el tiempo GNU (man time
) con respecto a la E / S, cambios de contexto, ...Respuestas:
La forma obvia de mantener un montón de archivos en la memoria caché es acceder a ellos con frecuencia. Linux es bastante bueno para arbitrar entre el intercambio y el almacenamiento en caché, por lo que sospecho que la diferencia de velocidad que observa no se debe realmente a que el sistema operativo no mantenga las cosas en la memoria caché, sino a alguna otra diferencia entre su uso de tmpfs y sus otros intentos.
Intenta observar lo que está haciendo IO en cada caso. La herramienta básica para eso es
iotop
. Otras herramientas pueden ser útiles; vea el desglose de carga de E / S del disco de Linux, por ruta o proceso del sistema de archivos , ¿Qué programa en Linux puede medir las E / S a lo largo del tiempo? y otros subprocesos en Server Fault.Aquí hay algunas hipótesis sobre lo que podría estar sucediendo. Si toma medidas, muéstreselas para que podamos confirmar o refutar estas hipótesis.
noatime
opción de montaje. Su solución tmpfs + rsync nunca lee del disco duro, por lo que nunca tiene que dedicar más tiempo a escribir notas.sync()
o porque el núcleo frecuentemente vacía sus memorias intermedias de salida, las escrituras tardarán más en un disco duro que en tmpfs.fuente
Linux por defecto usa la RAM como caché de disco. Como demostración, intente ejecutar
time find /some/dir/containing/a/lot/of/files > /dev/null
dos veces, la segunda vez es mucho más rápida ya que todos los inodos de disco se almacenan en caché. El punto aquí es cómo utilizar esta función del núcleo y detener su intento de reemplazarla.El punto es cambiar el
swappiness
. Consideremos tres tipos principales de uso de memoria: programas activos, programas inactivos y caché de disco. Obviamente, la memoria utilizada por los programas activos no debe intercambiarse y la elección entre otros dos es bastante arbitraria. ¿Desea un cambio rápido de programa o acceso rápido a archivos? Un intercambio bajo prefiere mantener los programas en la memoria (incluso si no se usa durante mucho tiempo) y un intercambio alto prefiere mantener más caché de disco (intercambiando programas no utilizados). (la escala de intercambio es de 0 a 100 y el valor predeterminado es 60)Mi solución a su problema es cambiar el intercambio a muy alto (90-95 por no decir 100) y cargar el caché:
Como lo adivina, debe tener suficiente memoria libre para almacenar en caché todos sus archivos fuente y archivos de objetos, así como el compilador, incluidos los archivos de encabezados, las bibliotecas vinculadas, su IDE y otros programas utilizados.
fuente
tmpfs
en el mismo caso también sería intercambiado.Forzar caché no es la forma correcta de hacer esto. Es mejor mantener las fuentes en el disco duro y compilarlas en tmpfs. Muchos sistemas de compilación, como qmake y CMake, admiten compilaciones fuera de la fuente.
fuente
El
inosync
demonio suena como si hiciera exactamente lo que quieres si vas a sincronizar a un disco ram. En lugar de rsyncing cada 10 segundos más o menos, utiliza la función de inotify de Linux para rsync cuando cambia un archivo. Lo encontré en el repositorio de Debian como elinosync
paquete, o su fuente está disponible en http://bb.xnull.de/projects/inosync/ .fuente
Esto parece funcionar para mí si quiero mantener ciertos archivos o todos los archivos en un determinado directorio en caché.
vmtouch parece hacer exactamente lo mismo. Ejemplo 5 puede haber lo que necesita.
Necesitaba ejecutarlo como root con
sudo
fuente
Dada suficiente memoria, su compilación del disco RAM no hace E / S. Esto puede acelerar cualquier cosa que lea o escriba archivos. I / O es una de las operaciones más lentas. Incluso si tiene todo en caché antes de la compilación, todavía tiene las E / S para escribir, aunque deberían tener un impacto mínimo.
Puede acelerar un poco cargando previamente todos los archivos en la memoria caché, pero el tiempo necesario para eso debe incluirse en los tiempos de compilación totales. Esto puede no darle mucha ventaja.
Construir el objeto y los archivos intermedios en RAM en lugar de en disco. Hacer compilaciones incrementales puede obtener ganancias significativas en construcciones frecuentes. En la mayoría de los proyectos hago una compilación limpia diaria y compilaciones incrementales en el medio. Las compilaciones de integración son siempre compilaciones limpias, pero trato de limitarlas a menos de una por día.
Puede obtener algo de rendimiento utilizando una partición ext2 con atime desactivado. Su fuente debe estar en control de versiones en un sistema de archivos registrado como ext3 / 4.
fuente
Como se indicó anteriormente, la forma obvia es leer toda la estructura del directorio y el contenido del archivo de lo que desea almacenar en caché.
Puede automatizar esto escribiendo un script para monitorear la salida de
vmstat 1
(use cualquier herramienta equivalente para su sistema operativo) y mantener una suma de la cantidad de bloques escritos y leídos. Una vez que la suma supera el umbral de su elección, lea todos los archivos que desea almacenar en caché, restablezca la suma y luego continúe monitoreando la salida de vmstat. Para leer archivos rápidamente: si su árbol contiene muchos archivos, evitefind ... -exec cat
, en su lugar, intente confind ... -print0 | xargs -0 cat
un programa personalizado que no ejecute cat para cada archivo.La supervisión de la E / S del disco es preferible a utilizar un intervalo fijo porque indica que debe volver a leer sus datos con mayor o menor frecuencia según la carga de la E / S del disco.
He utilizado este método automatizado con éxito en sistemas donde necesitaba algunas lecturas de archivos de índice para ser siempre rápidas, evitando la E / S del disco duro. También he usado strace para hacer una lista de cada archivo al que accedo cuando inicio sesión para poder mantener todo caliente en caché para inicios de sesión rápidos.
Puede que esta no sea la mejor solución posible, pero me fue bien.
fuente