Pourquoi MinGW est-il très lent?

J’utilise l’EDI Code :: Blocks avec GCC / MinGW sous Windows et j’essaie de créer une application wxWidgets qui a env. 20k lignes et 40 modules sources. Et cela se construit très très lentement.

La compilation d’un module C ++ dure 2 à 5 secondes et la liaison dure même 2 à 3 minutes.

C’est un code portable, et ce code se comstack très vite sous Linux. Je ne peux pas suivre la fenêtre de message de construction … L’ensemble du processus dure moins de 20 secondes.

J’ai essayé les réglages courants (par exemple, en-tête précompilé, désactiver les optimisations, etc.), mais rien n’a fonctionné.

Pourquoi est-ce si lent?

Êtes-vous sur un domaine Active Directory, mais pas immédiatement connecté à celui-ci?

Bien que je ne connaisse pas la raison pour laquelle MinGW serait lent, je me suis rendu compte que les ordinateurs appartenant à un domaine AD, mais ne pouvant pas atteindre le contrôleur AD, tardent à démarrer les exécutables (tels que rxvt.exe) et ceux qui sont en cours d’exécution subissent une pause ou un bégaiement (comme emacs, construit avec MinGW).

J’enquête toujours pour déterminer la cause réelle de ce comportement, mais je pensais le mentionner au cas où cela vous concernerait.

Beaucoup de choses “unixy” sur MinGW sont terriblement lentes, car Windows n’a pas de fork() . Windows a seulement CreateProcess() , ce qui est très différent. Les shells Unix et GNU Make effectuent beaucoup de bifurcation. Par conséquent, les exécuter sous MinGW donne des “émules”, qui sont vraiment lents.

Une autre chose qui en souffre est GNU Autotools, aussi, l’exécution de scripts ./configure lors de la construction d’applications “unixy” à partir de sources est également très lente. Cela peut devenir très gênant si vous devez le faire plusieurs fois (par exemple, lorsque vous rencontrez des problèmes pour obtenir la configuration nécessaire pour trouver toutes les bibliothèques).

Cette réponse explique plus en détail comment Cygwin et MinGW simulaient fork() , et cette réponse contient des explications plus récentes.

À partir de MSYS 1.0.19-1 , si le compte d’utilisateur est dans le domaine Active Directory et que le contrôleur de domaine est inaccessible, la MSYS DLL introduit un long délai avant de démarrer tout fichier exécutable MSYS (qui utilise la MSYS DLL ). Cela concerne MSYS et tous les utilitaires de ligne de commande du package CoreUtils, tels que ls , rm etc., généralement installés dans C:\MinGW\msys\1.0\bin .

Observations:

  • Lors du lancement des utilitaires à partir du shell MSYS bash , seul le démarrage du shell est affecté par le retard. Les utilitaires lancés à partir du shell n’ont pas d’impact.

  • Le délai peut varier, dans mon cas, il est 21 secondes.

  • L’exécution de tout utilitaire MSYS dans un délai de 10 à 20 secondes après le lancement de la commande différée démarre sans délai.
  • Le problème survient lorsque la machine est connectée à un autre réseau, lorsqu’elle est déconnectée de son domaine ou lorsque le nom d’hôte du contrôleur de domaine est modifié (problème dans mon cas). Pour vérifier si le contrôleur de domaine est accessible, ouvrez cmd et tapez echo %LOGONSERVER% , puis echo %LOGONSERVER% ping ou net view echo %LOGONSERVER% avec le nom d’hôte du contrôleur de domaine.

Pourquoi est-ce si lent:

  • Le code de la MSYS DLL dans uinfo.cc internal_getlogin() effectue deux appels système pour obtenir des informations sur l’utilisateur. Pour la première fois, il appelle NetUserGetInfo() pour récupérer le compte de l’utilisateur à partir de la machine locale. Il échoue pour les utilisateurs du domaine et l’appelle donc une seconde fois avec le serveur du LOGONSERVER de domaine LOGONSERVER variable LOGONSERVER . Si cet hôte n’est pas immédiatement accessible, il introduira un long délai jusqu’à ce que l’appel échoue à l’expiration du délai. L’application va démarrer peu de temps après.

Comment éviter ce problème, plusieurs solutions de contournement:

  • Soit tout exécuter à partir du shell MSYS, ou
  • Si la raison en est la modification du nom d’hôte du contrôleur de domaine, un redémarrage ou une nouvelle connexion permettra de résoudre le problème. Windows mettra automatiquement à jour LOGONSERVER avec le bon hôte de LOGONSERVER de domaine.
  • Si les outils MSYS sont appelés à partir de la commande Windows ou d’un script, définissez LOGONSERVER sur un hôte local pour éviter tout access au réseau. Par exemple, set LOGONSERVER=\\LOCALHOST fonctionné pour moi. Remarque: cette variable est définie à l’ouverture de session et sa modification globale dans la fenêtre Variables d’environnement Windows n’a aucun effet par rapport à sa définition dans cmd ou dans un script.
  • Je considère cela comme un bogue dans MinGW / MSYS. Le code dans MSYS2 et Cygwin est différent. J’ai vérifié MSYS2 et il n’a pas un tel problème.

Vous pouvez essayer d’utiliser une version plus récente du jeu d’outils. J’ai trouvé cela utile: http://nuwen.net/mingw.html Il contient tous les outils utilisés par MinGW et des API communes dans un seul gros paquet. Du site:

Ma dissortingbution MinGW (“distro”) est en x64 et contient actuellement GCC 6.1.0 et Boost 1.61.0.

MinGW est un portage de GCC vers Windows. Il est gratuit et simple à utiliser (enfin, aussi simple que jamais les chaînes d’outils). Il produit des exécutables Windows autonomes qui peuvent être dissortingbués de n’importe quelle manière.