2009-05-30 36 views
21

Estoy usando Code :: Blocks IDE con GCC/MinGW en Windows, y estoy tratando de construir una aplicación wxWidgets que tenga ca. 20k líneas y 40 módulos fuente. Y se construye muy, muy lento.¿Por qué MinGW es muy lento?

La compilación de un módulo C++ dura de 2 a 5 segundos y la vinculación dura incluso 2 o 3 minutos.

Es un código portable, y este código se compila muy rápido en Linux. No puedo seguir la ventana de generación de mensajes ... Todo el proceso dura menos de 20 segundos.

Probé los ajustes comunes (por ejemplo, encabezado precompilado, desactivación de optimizaciones, etc.), pero nada funcionó.

¿Por qué es tan lento?

+0

¿qué versión de gcc estás usando? do gcc --version en la línea de comandos para averiguar –

+0

La versión de gcc es v3.4.5 – Calmarius

Respuesta

13

¿Está en un dominio de Active Directory pero no está conectado de inmediato?

Si bien no tengo la "respuesta" de por qué MinGW sería lento, tengo la experiencia de que las computadoras que pertenecen a un dominio AD, pero no pueden alcanzar el controlador AD, tienen un retraso en comenzar los ejecutables (como rxvt.exe) y los que se están ejecutando actualmente experimentan una pausa o tartamudeo (como emacs, que se genera utilizando MinGW).

Todavía estoy investigando para determinar el verdadero causa de este comportamiento, pero pensé que lo mencionaría en caso de que se aplique a usted.

+5

+1 Estoy experimentando esto también, deshabilitando los resultados de mis adaptadores de red en el inicio inmediato. Poner entradas DNS falsas (127.0.0.1) para los controladores de dominio en mi archivo hosts hace que las cosas _mucho_ sean más rápidas, pero no tan rápido como deshabilitar la red por completo. –

+0

Nuestro controlador de AD está en: server.domain.com. Agregar "127.0.0.1 server.domain.com" a mi archivo de hosts hace el truco. – rcmadruga

+0

Gracias por esta sugerencia. ¡Hace años que me pregunto por qué esto ocurre solo en una de mis máquinas! Sucede que no está conectado a su dominio AD ... –

0

Puede intentar utilizar una versión más reciente del conjunto de herramientas. Encontré esto útil: http://nuwen.net/mingw.html Tiene todas las herramientas utilizadas por MinGW y API comunes en un solo paquete grande. Desde el sitio:

Mi distribución MinGW ("distribución") es x64-natal y actualmente contiene GCC 6.1.0 y Boost 1.61.0.

MinGW es un puerto de GCC para Windows. Es gratis y simple de usar (bueno, tan simple como los toolchains alguna vez se obtienen). Produce ejecutables de Windows independientes que se pueden distribuir de cualquier manera.

6

Muchas cosas "unixy" en MinGW son dolorosamente lentas, porque Windows no tiene fork(). Windows solo tiene CreateProcess(), que es bastante diferente. Unix shells y GNU hacen un montón de bifurcaciones, por lo que ejecutar estos en resultados MinGW en horquillas "emuladas", que son realmente lentos.

Otra cosa que sufre de esto es GNU Autotools, por lo que ejecutar scripts de ./configure al construir aplicaciones "unixy" desde las fuentes también es muy lento. Esto puede ser realmente molesto si necesita hacerlo muchas veces (por ejemplo, cuando tiene problemas al obtener configure para encontrar todas las bibliotecas).

This answer explica con más detalle cómo Cygwin y MinGW utilizan para simularfork() y this answer tiene más hasta la fecha explicación.

+1

¿Está tratando de decirnos que fork() realmente se usa para clonar el proceso actual en lugar de ser seguido por execp()? ¿Qué compilador/enlazador necesita clonar un proceso? –

+1

@ExcessPhase No estoy seguro de lo que quieres decir con eso. Los programas de Unix usan 'fork()' para crear procesos secundarios. Cuando compila ese programa Unix para MinGW, la llamada 'fork()' * todavía * necesita crear un proceso hijo como lo haría en Unix "real", incluso si 'fork()' es seguido por * exec *, no importa cuán lenta sea la horquilla emulada MinGW, porque el compilador no puede cambiar el código del programa para que funcione de manera más eficiente en Windows. – hyde

+0

@ExcessPhase Aunque, las cosas pueden haberse optimizado, agregué un segundo enlace de respuesta justo ahora. – hyde

1

Como de MSYS 1.0.19-1, si la cuenta de usuario está en el dominio Active Directory y el controlador de dominio (DC) es inalcanzable, entonces MSYS DLL introducirá un retraso largo antes de comenzar cualquier ejecutable MSYS (que utiliza MSYS DLL).Esto afecta a MSYS make y a todas las utilidades de línea de comandos del paquete CoreUtils como ls, rm, etc. que normalmente se instalan en C:\MinGW\msys\1.0\bin.

Observaciones:

  • Al poner en marcha los servicios públicos de MSYS bash cáscara, sólo el inicio de la cáscara es golpeado por el retraso. Las utilidades lanzadas desde el caparazón no tienen impacto.

  • La demora puede variar, en mi caso es de 21 segundos.

  • Ejecutando cualquier utilidad MSYS dentro de los 10-20 segundos después de que se inicie el comando demorado sin un nuevo retraso.
  • El problema se produce cuando la máquina está conectada a una red diferente, o cuando se desconecta de su dominio, o cuando cambia el nombre de host del controlador de dominio (problema en mi caso). Para verificar si DC es alcanzable, abra cmd y escriba echo %LOGONSERVER%, luego ping o net view con el nombre de host del DC.

¿Por qué es tan lento:

  • El código de MSYS DLL en uinfo.cc internal_getlogin() hace dos llamadas al sistema para obtener información del usuario. La primera vez llama al NetUserGetInfo() para recuperar la cuenta de usuario de la máquina local. Falla para los usuarios del dominio, por lo que lo llama por segunda vez con el servidor de DC tomado de la variable LOGONSERVER. Si este host no es accesible de inmediato, introducirá una gran demora hasta que la llamada falle en tiempo de espera. La aplicación comenzará poco después.

¿Cómo evitar este problema, varias soluciones:

  • O utilizar todo, desde la cáscara MSYS o
  • Si la razón es el cambio en DC nombre de host, a continuación, reiniciar o re-inicio de sesión Resuelve este problema. Windows actualizará automáticamente LOGONSERVER con el host DC correcto.
  • Si se invocan herramientas MSYS desde Windows cmd o una secuencia de comandos, establezca LOGONSERVER en un host local para evitar el acceso a la red. P.ej. set LOGONSERVER=\\LOCALHOST funcionó para mí. Nota: esta variable se configura en el inicio de sesión y cambiarla globalmente en la ventana Variables de entorno de Windows no tiene ningún efecto en comparación con establecerlo en cmd o un script.
  • Considero que esto es un error en MinGW/MSYS. El código en MSYS2 y Cygwin es diferente. Revisé MSYS2 y no tiene ese problema.