2009-05-30 9 views
21

Sto usando il codice :: Blocks IDE con GCC/MinGW su Windows e sto provando a creare un'applicazione wxWidgets che ha ca. 20k linee e 40 moduli sorgente. E si costruisce molto molto lentamente.Perché MinGW è molto lento?

La compilazione di un modulo C++ dura 2-5 secondi e il collegamento dura anche 2-3 minuti.

È un codice portatile e questo codice viene compilato molto velocemente su Linux. Non riesco a seguire la finestra del messaggio di build ... L'intero processo dura meno di 20 secondi.

Ho provato i ritocchi comuni (ad esempio, l'intestazione precompilata, disattivare le ottimizzazioni, ecc.), Ma non ha funzionato.

Perché è così lento?

+0

quale versione gcc stai usando? fai gcc --version alla riga di comando per scoprire –

+0

La versione gcc è v3.4.5 – Calmarius

risposta

13

Sei in un dominio di Active Directory, ma non connesso immediatamente ad esso?

Mentre non ho la "risposta" sul motivo per cui MinGW sarebbe lento, è stata la mia esperienza che i computer che appartengono a un dominio AD, ma non riescono a raggiungere il controller AD, hanno un ritardo nell'avvio i file eseguibili (come rxvt.exe) e quelli attualmente in esecuzione presentano una pausa o una balbuzie (come ad esempio emacs, che viene creata usando MinGW).

Sto ancora indagando per determinare l'effettivo causa di questo comportamento, ma ho pensato di menzionarlo nel caso in cui si applica a voi.

+5

+1 Anche io sto vivendo questo, disabilitando i miei adattatori di rete si ottiene l'avvio immediato. Inserire voci DNS fasulle (127.0.0.1) per i controller di dominio nel mio file hosts rende le cose _molto_ più veloci, ma non così veloci come disabilitare completamente la rete. –

+0

Il nostro controller AD è su: server.domain.com. Aggiungere "127.0.0.1 server.domain.com" al mio file hosts fa il trucco. – rcmadruga

+0

Grazie per questo suggerimento. Mi sono chiesto da secoli perché ciò avvenga solo su una delle mie macchine! Succede che non sia collegato al suo dominio AD ... –

0

È possibile provare a utilizzare una versione più recente del set di strumenti. Ho trovato questo utile: http://nuwen.net/mingw.html Ha tutti gli strumenti utilizzati da MinGW e API comuni in un unico grande pacchetto. Dal sito:

mia distribuzione MinGW ("distro") è x64 nativa e attualmente contiene GCC 6.1.0 e 1.61.0 Boost.

MinGW è una porta di GCC per Windows. È gratuito e semplice per l'uso di (beh, così semplice come mai i toolchain). Produce autonomamente i file eseguibili di Windows che possono essere distribuiti in qualsiasi modo.

6

Molte cose "unixy" su MinGW sono dolorosamente lente, perché Windows non ha fork(). Windows ha solo CreateProcess(), che è abbastanza diverso. Le shell Unix e GNU Make fanno un sacco di biforcazioni, quindi l'esecuzione di queste sotto MinGW risulta nei fork "emulati", che sono veramente lenti.

Un'altra cosa che ne deriva è GNU Autotools, quindi eseguire gli script ./configure quando si creano applicazioni "unixy" da sorgenti è anche molto lento. Questo può diventare davvero fastidioso se hai bisogno di farlo molte volte (ad esempio quando hai problemi con ottenere configurare per trovare tutte le librerie).

This answer spiega più in dettaglio come Cygwin e MinGW utilizzati per simularefork() e this answer ha più aggiornate spiegazione.

+1

Stai cercando di dirci, che fork() è davvero usato per clonare il processo corrente invece di essere seguito da execp()? Quale compilatore/linker deve clonare un processo? –

+1

@ExcessPhase Non sono sicuro di cosa intendi. I programmi Unix usano 'fork()' per creare processi figli. Quando compilate quel programma Unix per MinGW, la chiamata a 'fork() * ancora * deve creare un processo figlio proprio come farebbe in Unix" reale ", anche se' fork() 'è seguito da * exec *, no importa quanto sia lento il fork emulato MinGW, perché il compilatore non può cambiare il codice del programma per funzionare in modo più efficiente sotto Windows. – hyde

+0

@ExcessPhase Anche se le cose potrebbero essere state ottimizzate, ho aggiunto un link per la seconda risposta proprio ora. – hyde

1

Come di MSYS 1.0.19-1, se l'account utente è nel dominio Active Directory e il controller di dominio (DC) non è raggiungibile, allora MSYS DLL introdurrà un lungo ritardo prima di iniziare qualsiasi eseguibile MSYS (che utilizza MSYS DLL).Ciò ha effetto su MSYS make e su tutte le utilità da riga di comando del pacchetto CoreUtils come ls, rm ecc., Che in genere vengono installati in C:\MinGW\msys\1.0\bin.

Osservazioni:

  • Quando si lancia utilità dal MSYS bash conchiglia, avvio solo della shell viene colpito dal ritardo. Le utilità lanciate dalla shell non hanno impatto.

  • Il ritardo può variare, nel mio caso è 21 secondi.

  • Esecuzione di qualsiasi utilità MSYS entro 10-20 secondi dopo l'avvio del comando ritardato senza nuovo ritardo.
  • Il problema si verifica quando la macchina è connessa a una rete diversa o quando viene disconnessa dal suo dominio o quando il nome host del controller di dominio cambia (problema nel mio caso). Per verificare se DC è raggiungibile, apri cmd e digita echo %LOGONSERVER%, quindi ping o net view con il nome host del controller di dominio.

Perché è così lento:

  • Il codice di MSYS DLL in uinfo.cc internal_getlogin() rende due chiamate di sistema per ottenere informazioni sugli utenti. La prima volta chiama NetUserGetInfo() per recuperare l'account utente dal computer locale. Non riesce per gli utenti del dominio, quindi lo chiama la seconda volta con il server DC preso dalla variabile LOGONSERVER. Se questo host non è immediatamente accessibile, introdurrà un lungo ritardo fino a quando la chiamata non riesce al timeout. L'applicazione inizierà poco dopo.

Come evitare questo problema, diverse soluzioni:

  • O eseguire tutto da shell MSYS, o
  • se il motivo è la variazione del DC nome host, quindi un riavvio o ri-login sarà risolvere il problema. Windows aggiornerà automaticamente LOGONSERVER con l'host DC corretto.
  • Se gli strumenti MSYS vengono chiamati da Windows cmd o uno script, quindi impostare LOGONSERVER su un host locale per evitare l'accesso alla rete. Per esempio. set LOGONSERVER=\\LOCALHOST ha funzionato per me. Nota: questa variabile è impostata all'accesso e la sua modifica a livello globale nella finestra Variabili d'ambiente di Windows non ha alcun effetto se paragonata all'impostazione in cmd o in uno script.
  • Considero questo un bug in MinGW/MSYS. Il codice in MSYS2 e Cygwin è diverso. Ho controllato MSYS2 e non ha questo problema.