caching - Unidad de RAM para compilar: ¿existe tal cosa?
compilation folder (18)
Una respuesta (ver abajo) a una de las preguntas aquí mismo en Stack Overflow me dio una idea para una gran pequeña pieza de software que podría ser invaluable para los programadores de todo el mundo.
Estoy imaginando el software de la unidad RAM, pero con una diferencia crucial: sería una carpeta real en mi disco duro. Más específicamente, la carpeta que contiene el proyecto en el que estoy trabajando actualmente. De esta forma, cualquier construcción sería casi instantánea (o al menos un par de órdenes de magnitud más rápida). La unidad RAM sincronizaría sus contenidos con la unidad de disco duro en segundo plano utilizando solo recursos inactivos.
Una búsqueda rápida en Google no reveló nada, pero tal vez simplemente no sé cómo Google. Tal vez alguien sabe de ese tipo de software? Preferiblemente gratis, pero las tarifas razonables también pueden estar bien.
Agregado: Se sugirieron algunas soluciones que descarté al principio. Serían (sin ningún orden en particular):
- Compre una unidad de disco duro más rápida ( SSD quizás o 10K RPM). No quiero una solución de hardware. No solo el software tiene el potencial de ser más económico (freeware, ¿alguien?), Sino que también se puede usar en entornos donde las modificaciones de hardware no serían bienvenidas sino imposibles, por ejemplo, en la oficina.
- Deje que OS / HDD haga el almacenamiento en caché, ya que sabe mejor cómo usar su RAM libre. El OS / HDD tiene algoritmos de caché genéricos que almacenan en caché todo e intentan predecir qué datos serán más necesarios en el futuro. No tienen idea de que, para mí, la prioridad es mi carpeta de proyectos. Y como todos sabemos bastante bien, en realidad no lo almacenan en la memoria caché de todos modos. ;)
- Hay muchas unidades de RAM alrededor; usa uno de esos. Lo siento, eso sería imprudente. Necesito que mis datos se sincronicen nuevamente con el HDD cada vez que hay un poco de tiempo libre. En el caso de una falla de energía, podría soportar perder los últimos cinco minutos de trabajo, pero no todo desde mi última comprobación.
Se agregó 2: surgió una idea: use una unidad RAM normal más un sincronizador de carpeta de fondo (pero no quiero decir fondo ). ¿Existe tal cosa?
Añadido 3: Interesante. Acabo de probar una unidad de RAM simple en el trabajo. El tiempo de reconstrucción cae de ~ 14 segundos a ~ 7 segundos (no está mal), pero la construcción incremental sigue siendo ~ 5 segundos, como en el HDD. ¿Alguna idea de por qué? Utiliza aspnet_compiler
y aspnet_merge
. Tal vez hacen algo con otros archivos temporales en otro lugar?
4 añadido: ¡Oh, buen nuevo conjunto de respuestas! :) OK, tengo un poco más de información para todos los que te digan. :)
Una de las principales razones para esta idea no es el software mencionado anteriormente (14 segundos de tiempo de compilación), sino otro al que no tuve acceso en ese momento. Esta otra aplicación tiene una base de código de 100 MB, y su construcción completa demora aproximadamente 5 minutos. Ah sí, está en Delphi 5 , por lo que el compilador no está muy avanzado. :) Poner la fuente en una unidad RAM dio como resultado una GRAN diferencia. Lo tengo por debajo de un minuto, creo. No he medido. Entonces, para todos aquellos que dicen que el sistema operativo puede almacenar mejor las cosas en la memoria caché, me gustaría diferir.
Pregunta relacionada:
Nota sobre el primer enlace: la pregunta a la que se vincula ha sido eliminada porque era un duplicado. Pregunta:
¿Qué haces mientras compila tu código?
Y la respuesta de Dmitri Nesteruk a la que me vinculé fue:
Compilo casi al instante. En parte debido a que mis proyectos son pequeños, en parte debido al uso de discos RAM.
Hay muchas RAMDrives, usa una de esas. Lo siento, eso sería imprudente.
Solo si trabajas por completo en el disco RAM, lo cual es una tontería ...
Script de shell Psuedo-ish, ramMake:
# setup locations
$ramdrive = /Volumes/ramspace
$project = $HOME/code/someproject
# ..create ram drive..
# sync project directory to RAM drive
rsync -av $project $ramdrive
# build
cd $ramdrive
make
#optional, copy the built data to the project directory:
rsync $ramdrive/build $project/build
Dicho esto, su compilador puede hacer esto sin scripts adicionales. Simplemente cambie la ubicación de salida de su compilación a un disco RAM, por ejemplo en Xcode, en Preferencias, Building, "Place Build Products in:" y "Place Intermediate Build Files". en:".
Perfil. Asegúrese de hacer buenas mediciones de cada opción. Incluso puede comprar cosas que ya ha rechazado, medirlas y devolverlas, para que sepa que está trabajando con buenos datos.
Obtenga mucha RAM Los módulos DIMM de 2 GB son muy baratos; Los módulos DIMM de 4 GB cuestan un poco más de US $ 100 / ea, pero eso no es mucho dinero comparado con lo que las piezas de computadora cuestan solo unos años atrás. Ya sea que termine con un disco RAM o simplemente deje que el SO haga su trabajo, esto ayudará. Si está ejecutando Windows de 32 bits, tendrá que cambiar a 64 bits para hacer uso de cualquier cosa de más de 3 GB.
Live Mesh se puede sincronizar desde su unidad RAM local a la nube o a otra computadora, brindándole una copia de respaldo actualizada.
Mueva solo las salidas del compilador. Mantenga su código fuente en el disco físico real, pero dirija archivos .obj, .dll y .exe para que se creen en la unidad RAM.
Considera un DVCS . Clona desde la unidad real a un nuevo repositorio en la unidad RAM. "presione" sus cambios nuevamente al padre a menudo, diga cada vez que pasen todas sus pruebas.
Algunas ideas fuera de mi cabeza:
Use el Monitor de procesos de Sysinternals (no Process Explorer ) para verificar lo que ocurre durante una compilación; esto le permitirá ver si se usa %temp%
, por ejemplo (recuerde que los archivos de respuestas probablemente se crean con FILE_ATTRIBUTE_TEMPORARY que debe evitar las grabaciones en disco si es posible, sin embargo). He movido mi %TEMP%
a un disco RAM, y eso me da aceleraciones menores en general.
Obtenga un disco RAM que admita cargar / guardar automáticamente imágenes de disco, para que no tenga que usar scripts de arranque para hacer esto. La lectura / escritura secuencial de una sola imagen de disco es más rápida que la sincronización de muchos archivos pequeños.
Coloque los archivos de encabezado de uso frecuente / grande en el disco RAM y anule las rutas estándar del compilador para usar las copias de la unidad de RAM. Sin embargo, es probable que no proporcione una gran mejora después de las primeras compilaciones, ya que el sistema operativo almacena en caché los encabezados estándar.
Mantenga sus archivos fuente en su disco duro y sincronícelos con el disco RAM, y no al revés . Consulte MirrorFolder para realizar la sincronización en tiempo real entre carpetas: lo logra mediante un controlador de filtro, por lo que solo sincroniza lo necesario (y solo realiza cambios). Un archivo de 4 KB para escribir en 2 GB solo generará 4 KB de escritura en la carpeta de destino. ) Averigüe cómo hacer su compilación IDE desde la unidad RAM aunque los archivos fuente estén en su disco duro ... y tenga en cuenta que necesitará una unidad RAM grande para proyectos grandes.
En Linux (nunca mencionaste en qué sistema operativo estás, por lo que esto podría ser relevante) puedes crear dispositivos de bloque desde la RAM y montarlos como cualquier otro dispositivo de bloque (es decir, un HDD).
A continuación, puede crear scripts que se copien desde y hacia esa unidad al inicio / apagado, así como periódicamente.
Por ejemplo, podrías configurarlo para que tengas ~/code
y ~/code-real
. Su bloque RAM se monta en ~/code
al inicio, y luego se copia todo desde ~/code-real
(que está en su disco duro estándar). Al apagar todo se copiaría ( rsync ''d sería más rápido) de nuevo desde ~/code
hasta ~/code-real
. También es probable que desee que la secuencia de comandos se ejecute periódicamente, por lo que no perdió mucho trabajo en caso de un corte de energía, etc.
Ya no hago esto (lo usé para Opera cuando el 9.5 beta era lento, ya no es necesario).
Esto suena como el almacenamiento en caché de disco que su sistema operativo y / o disco duro manejará automáticamente (en distintos grados de rendimiento, sin duda).
Mi consejo es que, si no le gusta la velocidad de su disco, compre un disco de alta velocidad únicamente con fines de compilación. Menos trabajo de su parte y es posible que tenga la solución a sus problemas de compilación.
Dado que esta pregunta se planteó originalmente, los discos duros giratorios se han convertido en tortugas miserables en comparación con las SSD. Están muy cerca del disco RAM solicitado originalmente en una SKU que puedes comprar en Newegg o Amazon.
La ralentización del disco en la que incurre es principalmente de escritura, y posiblemente también debido a los escáneres de virus. También puede variar mucho entre sistemas operativos.
Con la idea de que las escrituras son más lentas, me sentiría tentado a configurar una compilación en la que los intermedios (por ejemplo, los archivos .o
) y los binarios salgan a una ubicación diferente, como un disco RAM.
A continuación, podría vincular esta carpeta bin / intermedia a medios más rápidos (utilizando un enlace simbólico o un punto de unión NTFS ).
Lo que puede ser muy beneficioso incluso en una máquina de un solo núcleo es la fabricación paralela. La I/O disco es un factor bastante importante en el proceso de compilación. Generar dos instancias de compilador por núcleo de CPU realmente puede aumentar el rendimiento. Como una instancia de compilador bloquea en E / S, la otra normalmente puede saltar a la parte intensiva de la CPU de compilación.
Debes asegurarte de que tienes la RAM para soportar esto (no debería ser un problema en una estación de trabajo moderna), de lo contrario terminarás cambiando y eso frustra el propósito.
En GNU make puedes simplemente usar -j[n]
donde [n]
es el número de procesos simultáneos para generar. Sin embargo, asegúrese de tener el árbol de dependencias correcto antes de intentarlo o los resultados pueden ser impredecibles.
Otra herramienta que es realmente útil (en forma paralela) es distcc . Funciona como un regalo con GCC (si puedes usar GCC o algo con una interfaz de línea de comando similar). distcc realmente divide la tarea de compilación fingiendo ser el compilador y las tareas de generación en servidores remotos. Usted lo llama de la misma manera que llamaría a GCC, y aprovecha la opción make -j [n] para llamar a muchos procesos distcc.
En uno de mis trabajos anteriores teníamos una compilación bastante intensiva del sistema operativo Linux que se realizaba casi todos los días durante un tiempo. Agregar un par de máquinas de construcción dedicadas y poner distcc en algunas estaciones de trabajo para aceptar trabajos de compilación nos permitió reducir los tiempos de construcción de medio día a menos de 60 minutos para una compilación completa del espacio de usuario de OS +.
Hay muchas otras herramientas para acelerar las compilaciones existentes. Es posible que desee investigar más que crear discos RAM; algo que parece que tendrá muy poca ganancia ya que el sistema operativo está haciendo un caché de disco con RAM. Los diseñadores de sistemas operativos pasan mucho tiempo almacenando en caché correctamente para la mayoría de las cargas de trabajo; son (colectivamente) más inteligentes que usted, por lo que no me gustaría intentarlo mejor que ellos.
Si mastica RAM para disco RAM, el sistema operativo tiene menos memoria RAM de trabajo para almacenar datos y ejecutar su código -> terminará con más intercambio y peor rendimiento de disco que de lo contrario (nota: debe perfilar esta opción antes de descartar por completo eso).
Me pregunto si podría construir algo así como un software RAID 1 donde tenga un disco físico / partición como miembro y un trozo de RAM como miembro.
Apuesto que con un poco de ajuste y una configuración realmente extraña uno podría hacer que Linux haga esto. Sin embargo, no estoy convencido de que valga la pena el esfuerzo.
Me sorprende cuánta gente sugiere que el sistema operativo puede hacer un mejor trabajo para resolver sus necesidades de almacenamiento en caché de lo que puede hacerlo en este caso especializado. Si bien no hice esto para la compilación, sí lo hice para procesos similares y terminé usando un disco RAM con scripts que automatizaban la sincronización.
En este caso, creo que elegiría un sistema de control de fuente moderno. En cada compilación verificaría automáticamente el código fuente (a lo largo de una rama experimental si es necesario) de modo que cada compilación daría como resultado que los datos se guarden.
Para comenzar el desarrollo, inicie el disco RAM y extraiga la línea base actual. Realice la edición, compilación, edición, compilación, etc., todo mientras las ediciones se guardan para usted.
Haga la verificación final cuando esté contento, y ni siquiera tiene que involucrar su unidad de disco duro normal.
Pero hay sincronizadores de fondo que automatizarán las cosas: el problema es que tampoco se optimizarán para la programación y es posible que deban hacerse escaneos completos de directorios y archivos ocasionalmente para detectar cambios. Un sistema de control de código fuente está diseñado exactamente para este propósito, por lo que es probable que tenga una sobrecarga menor aunque exista en la configuración de su compilación.
Tenga en cuenta que una tarea de sincronización en segundo plano, en el caso de un corte de energía, no está definida. Tendría que averiguar qué se guardó y qué no se guardó si las cosas salieron mal. Con un punto de guardado definido (en cada compilación, o forzado a mano) tendrías una muy buena idea de que estaba al menos en un estado en el que pensabas que podrías compilarlo. Use un VCS y puede compararlo fácilmente con el código anterior y ver qué cambios ya ha aplicado.
Mi solución final al problema es vmtouch: https://hoytech.com/vmtouch/ Esta herramienta bloquea la carpeta actual en caché (RAM) y vmtouch daemonizes en segundo plano.
sudo vmtouch -d -L ./
Pon esto en shell rc para un acceso rápido:
alias cacheThis = ''sudo vmtouch -d -L ./''
Busqué una secuencia de comandos preparada por bastante tiempo, porque no quería perder mucho tiempo escribiendo mi propio script ramdisk-rsync. Estoy seguro de que me habría perdido algunos casos extremos, lo que sería bastante desagradable si se tratara de un código importante. Y nunca me gustó el enfoque de votación.
Vmtouch parece ser la solución perfecta. Además, no desperdicia memoria como lo hace un ramdisk de tamaño fijo. No hice un benchmark, porque el 90% de mi carpeta 1Gig source + build ya estaba en la memoria caché, pero al menos se siente más rápido;)
No tengo exactamente lo que estás buscando, pero ahora estoy usando una combinación de Ramdisk y DRAM ramdisk . Como esto es Windows, tengo un límite de 3 GB para la memoria del núcleo, lo que significa que no puedo usar demasiada memoria para un disco RAM. 4 GB extra en el 9010 realmente lo mece. Dejo que mi IDE almacene todas sus cosas temporales en el disco RAM de estado sólido y también en el repositorio de Maven . El disco DRAM RAM tiene una batería de respaldo en la tarjeta flash. Esto suena como un anuncio, pero realmente es una excelente configuración.
El disco DRAM tiene dos puertos SATA-300 y sale con una búsqueda promedio de 0.0 ms en la mayoría de las pruebas;) ¿Algo para la media navideña?
Sí, he encontrado el mismo problema. Y después de infructuosas búsquedas en Google, acabo de escribir un Servicio de Windows para realizar copias de seguridad de la unidad RAM (en realidad, cualquier carpeta, porque la unidad RAM se puede montar, por ejemplo, en el escritorio).
http://bitbucket.org/xkip/transparentbackup Puede especificar el intervalo para la exploración completa (5 minutos predeterminados). Y un intervalo para escanear solo los archivos notificados (predeterminado 30 segundos). El escaneo detecta los archivos cambiados usando el atributo ''archivo'' (el sistema operativo restablece ese archivo especialmente para propósitos de archivo). Solo se realizan copias de seguridad de los archivos modificados de esa manera.
El servicio deja un archivo de marcador especial para asegurarse de que la copia de seguridad de destino sea exactamente una copia de seguridad de la fuente. Si la fuente está vacía y no contiene un archivo de marcador, el servicio realiza la restauración automática desde la copia de seguridad. Por lo tanto, puede destruir fácilmente la unidad RAM y crearla de nuevo con la restauración automática de datos. Es mejor utilizar una unidad RAM que pueda crear una partición en el inicio del sistema para que funcione de forma transparente.
Otra solución que he detectado recientemente es SuperSpeed SuperCache .
Esta compañía también tiene un disco RAM, pero ese es otro software. SuperCache le permite usar RAM adicional para el almacenamiento en caché a nivel de bloque (es muy diferente de la caché de archivos), y otra opción: duplicar la unidad a la memoria RAM por completo. En cualquier escenario, puede especificar la frecuencia con la que debe volver a colocar los bloques sucios en la unidad de disco duro, lo que hace que las escrituras sean similares a las de la unidad RAM, pero el escenario espejo también hace lecturas similares a las de la unidad RAM. Puede crear una partición pequeña, por ejemplo, 2 GB (con Windows) y asignar la partición completa a la RAM.
Una cosa interesante y muy útil acerca de esa solución: puede cambiar las opciones de almacenamiento en caché y duplicación en cualquier momento de forma instantánea con dos clics. Por ejemplo, si desea recuperar sus 2 GB para gamimg o máquina virtual, puede dejar de duplicar al instante y liberar la memoria. Incluso los identificadores de archivo abiertos no se rompen: la partición continúa funcionando, pero como unidad habitual.
EDITAR: También recomiendo que mueva la carpeta TEMP a la unidad de memoria RAM, porque los compiladores generalmente hacen mucho trabajo con la temperatura. En mi caso, me dio otro 30% de velocidad de compilación.
Solíamos hacer esto hace años para un macrocompilador 4GL ; si coloca la biblioteca de macros y las bibliotecas de soporte y su código en un disco RAM, compilar una aplicación (en un 80286) pasaría de 20 minutos a 30 segundos.
Su SO guardará cosas en la memoria mientras funciona. Un disco RAM puede parecer más rápido, pero eso se debe a que no tiene en cuenta los tiempos de "copiar a RAMDisk" y "copiar de RAMDisk". Dedicar RAM a un disco RAM de tamaño fijo solo reduce la memoria disponible para el almacenamiento en caché. El sistema operativo sabe mejor qué necesita estar en la memoria RAM.
Tal como dice James Curran, el hecho de que la mayoría de los programas siguen la ley de la localidad de referencias, el número frecuente de páginas de códigos y datos se reducirá con el tiempo a un tamaño manejable por la memoria caché de disco del sistema operativo.
Los discos RAM fueron útiles cuando los sistemas operativos se construyeron con limitaciones tales como cachés estúpidos (Win 3.x, Win 95, DOS). La ventaja del disco RAM es cercana a cero y si asigna mucha RAM, absorberá la memoria disponible para el administrador de caché del sistema, lo que perjudicará el rendimiento general del sistema. La regla de oro es: deja que tu núcleo haga eso. Esto es lo mismo que los programas de "desfragmentación de memoria" o "optimizadores": en realidad fuerzan a las páginas a salir de la memoria caché (para obtener más RAM eventualmente), pero causando que el sistema haga una gran cantidad de fallas de página con el tiempo cuando los programas cargados empiece a pedir el código / datos que fueron eliminados.
Por lo tanto, para obtener más rendimiento, obtenga un subsistema de hardware de E / S de disco rápido, tal vez RAID, CPU más rápida, mejor chipset (¡sin VIA!), Más memoria RAM física, etc.
Tuve la misma idea e hice algunas investigaciones. Encontré las siguientes herramientas que hacen lo que estás buscando:
Sin embargo, el segundo no pude lograr trabajar en Windows 7 de 64 bits, y parece que no se mantiene en este momento.
El disco RAM de VSuite en las otras manos funciona muy bien. Desafortunadamente no pude medir ningún aumento de rendimiento significativo en comparación con el disco SSD en su lugar.
Use https://wiki.archlinux.org/index.php/Ramdisk para crear el disco RAM.
Luego escribí estas secuencias de comandos para mover directorios hacia y desde el disco RAM. La copia de seguridad se realiza en un archivo tar antes de pasar al disco RAM. El beneficio de hacerlo de esta manera es que la ruta permanece igual, por lo que no es necesario que cambien todos sus archivos de configuración. Cuando haya terminado, use uramdir
para volver al disco.
Editar: código C agregado que ejecutará cualquier comando que se le dé en un intervalo en segundo plano. Lo estoy enviando con tar
--update
para actualizar el archivo si hay algún cambio.
Creo que esta solución de uso general supera una solución única a algo muy simple. BESO
Asegúrate de cambiar la ruta a rdbackupd
ramdir
#!/bin/bash
# May need some error checking for bad input.
# Convert relative path to absolute
# /bin/pwd gets real path without symbolic link on my system and pwd
# keeps symbolic link. You may need to change it to suit your needs.
somedir=`cd $1; /bin/pwd`;
somedirparent=`dirname $somedir`
# Backup directory
/bin/tar cf $somedir.tar $somedir
# Copy, tried move like https://wiki.archlinux.org/index.php/Ramdisk
# suggests, but I got an error.
mkdir -p /mnt/ramdisk$somedir
/bin/cp -r $somedir /mnt/ramdisk$somedirparent
# Remove directory
/bin/rm -r $somedir
# Create symbolic link. It needs to be in parent of given folder.
/bin/ln -s /mnt/ramdisk$somedir $somedirparent
#Run updater
~/bin/rdbackupd "/bin/tar -uf $somedir.tar $somedir" &
uramdir
#!/bin/bash
#Convert relative path to absolute
#somepath would probably make more sense
# pwd and not /bin/pwd so we get a symbolic path.
somedir=`cd $1; pwd`;
# Remove symbolic link
rm $somedir
# Copy dir back
/bin/cp -r /mnt/ramdisk$somedir $somedir
# Remove from ramdisk
/bin/rm -r /mnt/ramdisk$somedir
# Stop
killall rdbackupd
rdbackupd.cpp
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <signal.h>
#include <sys/time.h>
struct itimerval it;
char* command;
void update_archive(int sig)
{
system(command);
}
int main(int argc, char**argv)
{
it.it_value.tv_sec = 1; // Start right now
it.it_value.tv_usec = 0;
it.it_interval.tv_sec = 60; // Run every 60 seconds
it.it_interval.tv_usec = 0;
if (argc < 2)
{
printf("rdbackupd: Need command to run/n");
return 1;
}
command = argv[1];
signal(SIGALRM, update_archive);
setitimer(ITIMER_REAL, &it, NULL); // Start
while(true);
return 0;
}
Ver Aceleración emerge con tmpfs (wiki de Gentoo Linux ).
Agilizar las compilaciones usando unidades de RAM bajo Gentoo fue el tema de un tutorial escrito hace muchos eones. Proporciona un ejemplo concreto de lo que se ha hecho. Lo esencial es que todos los archivos intermedios de origen y compilación se redirigen a un disco RAM para su compilación, mientras que los archivos binarios finales se dirigen al disco duro para su instalación.
Además, le recomiendo que explore el mantenimiento de su fuente en el disco duro, pero git push
inserte sus últimos cambios de fuente en un depósito de clones que resida en el disco RAM. Compila el clon. Use su script favorito para copiar los binarios creados.
Espero que eso ayude.