Sé que esto no es tanto una pregunta de programación, pero es relevante.
Trabajo en un proyecto multiplataforma bastante grande . En Windows uso VC ++ 2008. En Linux uso gcc. Hay alrededor de 40k archivos en el proyecto. Windows es 10x a 40x más lento que Linux al compilar y vincular el mismo proyecto. ¿Cómo puedo arreglar eso?
Una compilación incremental de un solo cambio 20 segundos en Linux y> 3 minutos en Windows. ¿Por qué? Incluso puedo instalar el enlazador 'gold' en Linux y reducir ese tiempo a 7 segundos.
Del mismo modo, git es 10x a 40x más rápido en Linux que Windows.
En el caso de git, ¿es posible que git no esté utilizando Windows de la manera óptima sino VC ++? Uno pensaría que Microsoft querría hacer que sus propios desarrolladores fueran lo más productivos posible y una compilación más rápida contribuiría en gran medida a eso. ¿Quizás están tratando de alentar a los desarrolladores a C #?
Como prueba simple, encuentre una carpeta con muchas subcarpetas y haga una simple
dir /s > c:\list.txt
en Windows Hazlo dos veces y cronometra la segunda ejecución para que se ejecute desde el caché. Copie los archivos a Linux y realice las 2 ejecuciones equivalentes y cronometre la segunda ejecución.
ls -R > /tmp/list.txt
Tengo 2 estaciones de trabajo con exactamente las mismas especificaciones. HP Z600s con 12 gig de ram, 8 núcleos a 3.0 ghz. En una carpeta con ~ 400k archivos, Windows tarda 40 segundos, Linux tarda <1 segundo.
¿Hay alguna configuración de registro que pueda configurar para acelerar Windows? ¿Lo que da?
Algunos enlaces ligeramente relevantes, relevantes para los tiempos de compilación, no necesariamente de E / S.
Aparentemente hay un problema en Windows 10 (no en Windows 7) que al cerrar un proceso tiene un bloqueo global . Al compilar con múltiples núcleos y, por lo tanto, con múltiples procesos, este problema afecta.
La
/analyse
opción puede afectar negativamente a perf porque carga un navegador web . (No es relevante aquí pero es bueno saberlo)
Respuestas:
A menos que aparezca un pirata informático de sistemas Windows, no obtendrá más que comentarios partidistas (que no haré) y especulaciones (que es lo que voy a intentar).
Sistema de archivos: debe intentar las mismas operaciones (incluida la
dir
) en el mismo sistema de archivos. Encontré esto que compara algunos sistemas de archivos para varios parámetros.Almacenamiento en caché. Una vez intenté ejecutar una compilación en Linux en un disco RAM y descubrí que era más lento que ejecutarlo en el disco gracias a la forma en que el núcleo se encarga del almacenamiento en caché. Este es un punto de venta sólido para Linux y podría ser la razón por la cual el rendimiento es tan diferente.
Malas especificaciones de dependencia en Windows. Tal vez las especificaciones de dependencia de cromo para Windows no son tan correctas como para Linux. Esto puede generar compilaciones innecesarias cuando realiza un pequeño cambio. Es posible que pueda validar esto utilizando la misma cadena de herramientas del compilador en Windows.
fuente
Algunas ideas
fsutil behavior set disable8dot3 1
fsutil behavior set mftzone 2
cambie el último número a 3 o 4 para aumentar el tamaño en incrementos adicionales del 12.5%. Después de ejecutar el comando, reinicie y luego cree el sistema de archivos.fsutil behavior set disablelastaccess 1
fsutil behavior set memoryusage 2
fuente
NTFS ahorra tiempo de acceso a archivos cada vez. Puede intentar deshabilitarlo: "conjunto de comportamiento fsutil disablelastaccess 1" (reiniciar)
fuente
El problema con Visual C ++ es, hasta donde puedo decir, que no es una prioridad para el equipo compilador optimizar este escenario. Su solución es que use su función de encabezado precompilado. Esto es lo que han hecho proyectos específicos de Windows. No es portátil, pero funciona.
Además, en Windows, generalmente tiene escáneres de virus, así como herramientas de restauración y búsqueda del sistema que pueden arruinar sus tiempos de compilación por completo si monitorean su carpeta Buid por usted. El monitor de recursos de Windows 7 puede ayudarlo a detectarlo. Tengo una respuesta aquí con algunos consejos adicionales para optimizar los tiempos de compilación de vc ++ si está realmente interesado.
fuente
Personalmente, encontré que ejecutar una máquina virtual de Windows en Linux logró eliminar una gran parte de la lentitud de IO en Windows, probablemente porque Linux VM estaba haciendo mucho almacenamiento en caché que Windows no.
Al hacerlo, pude acelerar los tiempos de compilación de un gran proyecto C ++ (250Kloc) en el que estaba trabajando, desde unos 15 minutos hasta unos 6 minutos.
fuente
La dificultad para hacerlo se debe al hecho de que C ++ tiende a extenderse y al proceso de compilación en muchos archivos pequeños e individuales. Eso es algo en lo que Linux es bueno y Windows no. Si desea hacer un compilador de C ++ realmente rápido para Windows, intente mantener todo en RAM y toque el sistema de archivos lo menos posible.
Así es también como hará una cadena de compilación C ++ de Linux más rápida, pero es menos importante en Linux porque el sistema de archivos ya está haciendo mucho ajuste por usted.
La razón de esto se debe a la cultura Unix: históricamente, el rendimiento del sistema de archivos ha sido una prioridad mucho más alta en el mundo Unix que en Windows. No quiere decir que no haya sido una prioridad en Windows, solo que en Unix ha sido una prioridad más alta.
Acceso al código fuente.
No puedes cambiar lo que no puedes controlar. La falta de acceso al código fuente de Windows NTFS significa que la mayoría de los esfuerzos para mejorar el rendimiento han sido a través de mejoras de hardware. Es decir, si el rendimiento es lento, puede solucionar el problema mejorando el hardware: el bus, el medio de almacenamiento, etc. Solo puede hacer mucho si tiene que solucionar el problema, no solucionarlo.
El acceso al código fuente de Unix (incluso antes del código abierto) estaba más extendido. Por lo tanto, si quisiera mejorar el rendimiento, primero lo abordaría en software (más barato y más fácil) y en hardware en segundo lugar.
Como resultado, hay muchas personas en el mundo que obtuvieron sus doctorados al estudiar el sistema de archivos Unix y encontrar formas novedosas de mejorar el rendimiento.
Unix tiende hacia muchos archivos pequeños; Windows tiende a unos pocos (o un solo) gran archivo.
Las aplicaciones Unix tienden a manejar muchos archivos pequeños. Piense en un entorno de desarrollo de software: muchos archivos fuente pequeños, cada uno con su propio propósito. La etapa final (vinculación) crea un archivo grande, pero ese es un pequeño porcentaje.
Como resultado, Unix tiene un sistema altamente optimizado para abrir y cerrar archivos, escanear directorios, etc. La historia de los trabajos de investigación de Unix abarca décadas de optimizaciones del sistema de archivos que piensan mucho en mejorar el acceso a directorios (búsquedas y escaneos de directorios completos), apertura inicial de archivos, etc.
Las aplicaciones de Windows tienden a abrir un archivo grande, mantenerlo abierto durante mucho tiempo, cerrarlo cuando haya terminado. Piensa en MS-Word. msword.exe (o lo que sea) abre el archivo una vez y lo agrega durante horas, actualiza los bloques internos, etc. El valor de optimizar la apertura del archivo sería una pérdida de tiempo.
La historia de la evaluación comparativa y la optimización de Windows ha estado en la rapidez con que uno puede leer o escribir archivos largos. Eso es lo que se optimiza.
Lamentablemente, el desarrollo de software ha tendido a la primera situación. Heck, el mejor sistema de procesamiento de texto para Unix (TeX / LaTeX) lo alienta a colocar cada capítulo en un archivo diferente y # incluirlos todos juntos.
Unix se centra en el alto rendimiento; Windows se centra en la experiencia del usuario
Unix comenzó en la sala de servidores: sin interfaz de usuario. Lo único que ven los usuarios es la velocidad. Por lo tanto, la velocidad es una prioridad.
Windows comenzó en el escritorio: los usuarios solo se preocupan por lo que ven y ven la interfaz de usuario. Por lo tanto, se gasta más energía en mejorar la interfaz de usuario que el rendimiento.
El ecosistema de Windows depende de la obsolescencia planificada. ¿Por qué optimizar el software cuando el nuevo hardware está a solo un año o dos?
No creo en las teorías de conspiración, pero si lo hiciera, señalaría que en la cultura de Windows hay menos incentivos para mejorar el rendimiento. Los modelos comerciales de Windows dependen de que las personas compren máquinas nuevas, como un reloj. (Es por eso que el precio de las acciones de miles de empresas se ve afectado si MS envía un sistema operativo tarde o si Intel pierde una fecha de lanzamiento del chip). Esto significa que hay un incentivo para resolver problemas de rendimiento diciéndole a la gente que compre nuevo hardware; no mejorando el verdadero problema: sistemas operativos lentos. Unix proviene de la academia, donde el presupuesto es limitado y puedes obtener tu doctorado inventando una nueva forma de acelerar los sistemas de archivos; rara vez alguien en la academia obtiene puntos por resolver un problema emitiendo una orden de compra.
Además, como Unix es de código abierto (incluso cuando no lo era, todos tenían acceso a la fuente), cualquier estudiante de doctorado aburrido puede leer el código y hacerse famoso al mejorarlo. Eso no sucede en Windows (MS tiene un programa que brinda a los académicos acceso al código fuente de Windows, rara vez se aprovecha). Mire esta selección de documentos de rendimiento relacionados con Unix: http://www.eecs.harvard.edu/margo/papers/ o busque la historia de los documentos de Osterhaus, Henry Spencer u otros. Heck, uno de los debates más grandes (y más agradables de ver) en la historia de Unix fue el ida y vuelta entre Osterhaus y Selzer http://www.eecs.harvard.edu/margo/papers/usenix95-lfs/supplement/rebuttal. html No ves que ese tipo de cosas sucedan en el mundo de Windows. Es posible que veas vendedores que se superan entre sí, pero eso parece ser mucho más raro últimamente, ya que la innovación parece estar a nivel del cuerpo de los estándares.
Así lo veo yo.
Actualización: si observa las nuevas cadenas de compiladores que están saliendo de Microsoft, será muy optimista porque gran parte de lo que están haciendo hace que sea más fácil mantener toda la cadena de herramientas en RAM y repetir menos trabajo. Cosas muy impresionantes.
fuente
Enlace incremental
Si la solución VC 2008 está configurada como proyectos múltiples con salidas .lib, debe configurar "Usar entradas de dependencia de biblioteca"; esto hace que el enlazador se vincule directamente con los archivos .obj en lugar del .lib. (Y en realidad hace que sea un enlace incremental).
Rendimiento transversal del directorio
Es un poco injusto comparar el rastreo de directorios en la máquina original con el rastreo de un directorio recién creado con los mismos archivos en otra máquina. Si desea una prueba equivalente, probablemente debería hacer otra copia del directorio en la máquina fuente. (Todavía puede ser lento, pero podría deberse a cualquier cantidad de cosas: fragmentación del disco, nombres de archivo cortos, servicios en segundo plano, etc.) Aunque creo que los problemas de
dir /s
rendimiento tienen más que ver con escribir la salida que con medir el archivo real Rendimiento transversal. Evendir /s /b > nul
es lento en mi máquina con un gran directorio.fuente
Estoy bastante seguro de que está relacionado con el sistema de archivos. Trabajo en un proyecto multiplataforma para Linux y Windows donde todo el código es común, excepto donde el código dependiente de la plataforma es absolutamente necesario. Usamos Mercurial, no git, por lo que no se aplica la "Linuxness" de git. Obtener cambios desde el repositorio central lleva una eternidad en Windows en comparación con Linux, pero tengo que decir que nuestras máquinas con Windows 7 funcionan mucho mejor que las de Windows XP. Compilar el código después de eso es aún peor en VS 2008. No es solo hg; CMake también funciona mucho más lento en Windows, y ambas herramientas usan el sistema de archivos más que cualquier otra cosa.
El problema es tan grave que la mayoría de nuestros desarrolladores que trabajan en un entorno de Windows ya ni siquiera se molestan en hacer compilaciones incrementales: descubren que hacer una compilación de unidad es más rápido.
Por cierto, si desea disminuir drásticamente la velocidad de compilación en Windows, sugeriría la mencionada construcción de la unidad. Implementar correctamente en el sistema de compilación es complicado (lo hice para nuestro equipo en CMake), pero una vez hecho esto, acelera automáticamente las cosas para nuestros servidores de integración continua. Dependiendo de cuántos binarios está escupiendo su sistema de construcción, puede obtener una mejora de 1 a 2 órdenes de magnitud. Su experiencia puede ser diferente. En nuestro caso, creo que aceleró las compilaciones de Linux tres veces y las de Windows en un factor de 10, pero tenemos muchas bibliotecas y ejecutables compartidos (lo que disminuye las ventajas de una compilación de unidad).
fuente
¿Cómo construyes tu gran proyecto multiplataforma? Si está utilizando archivos MAKE comunes para Linux y Windows, podría degradar fácilmente el rendimiento de Windows en un factor de 10 si los archivos MAKE no están diseñados para ser rápidos en Windows.
Acabo de arreglar algunos makefiles de un proyecto multiplataforma usando makefiles comunes (GNU) para Linux y Windows. ¡Make está comenzando un
sh.exe
proceso para cada línea de una receta que causa la diferencia de rendimiento entre Windows y Linux!De acuerdo con la documentación de GNU make
debería resolver el problema, pero esta característica (actualmente) no es compatible con Windows make. ¡Así que reescribir las recetas para que estén en líneas lógicas únicas (por ejemplo, agregando; \ o \ al final de las líneas del editor actual) funcionó muy bien!
fuente
En mi humilde opinión, se trata de rendimiento de E / S de disco. El orden de magnitud sugiere que muchas de las operaciones van al disco en Windows, mientras que se manejan en la memoria en Linux, es decir, Linux se almacena mejor en caché. Su mejor opción en Windows será mover sus archivos a un disco, servidor o sistema de archivos rápido. Considere comprar una unidad de estado sólido o mover sus archivos a un disco RAM o un servidor NFS rápido.
Ejecuté las pruebas de recorrido del directorio y los resultados están muy cerca de los tiempos de compilación informados, lo que sugiere que esto no tiene nada que ver con los tiempos de procesamiento de la CPU o los algoritmos del compilador / enlazador.
Tiempos medidos como se sugirió anteriormente atravesando el árbol de directorio de cromo:
Para las pruebas, extraje las fuentes de cromo (ambas en win / linux)
Para medir el tiempo que corrí
Apagué las marcas de tiempo de acceso, mi escáner de virus y aumenté la configuración del administrador de caché en Windows (> 2 Gb de RAM), todo sin mejoras notables. El hecho es que, desde el primer momento, Linux funcionó 50 veces mejor que Windows con una cuarta parte de la RAM.
Para cualquiera que quiera afirmar que los números son incorrectos, por cualquier razón, pruébelo y publique sus hallazgos.
fuente
Intenta usar jom en lugar de nmake
Consíguelo aquí: https://github.com/qt-labs/jom
El hecho es que nmake está usando solo uno de sus núcleos, jom es un clon de nmake que hace uso de procesadores multinúcleo.
GNU lo hace listo para usar gracias a la opción -j, que podría ser una razón de su velocidad frente a Microsoft nmake.
jom funciona ejecutando en paralelo diferentes comandos make en diferentes procesadores / núcleos. ¡Pruébalo y siente la diferencia!
fuente
Quiero agregar solo una observación usando Gnu make y otras herramientas de las herramientas MinGW en Windows: parecen resolver los nombres de host incluso cuando las herramientas ni siquiera pueden comunicarse a través de IP. Supongo que esto es causado por alguna rutina de inicialización del tiempo de ejecución MinGW. Ejecutar un proxy DNS local me ayudó a mejorar la velocidad de compilación con estas herramientas.
Antes de que me doliera la cabeza porque la velocidad de compilación se redujo en un factor de aproximadamente 10 cuando abrí una conexión VPN en paralelo. En este caso, todas estas búsquedas de DNS pasaron por la VPN.
Esta observación también podría aplicarse a otras herramientas de compilación, no solo basadas en MinGW y, mientras tanto, podría haber cambiado en la última versión de MinGW.
fuente
Recientemente pude archivar otra forma de acelerar la compilación en aproximadamente un 10% en Windows usando Gnu make reemplazando mingw bash.exe con la versión de win-bash
(El win-bash no es muy cómodo con respecto a la edición interactiva).
fuente