Ralentissement de Windows, partie 2: création de processus



Windows a longtemps été blâmé pour la lenteur des opérations sur les fichiers et la création de processus. Avez-vous déjà essayé de les ralentir encore plus? Cet article montrera la technique pour ralentir progressivement la création de processus dans Windows (à l'infini) de manière invisible pour la plupart des utilisateurs!

Et bien sûr, l'article vous expliquera également comment détecter et éviter ce problème.

C'est un vrai problème que j'ai rencontré au début de l'année, et l'article explique comment je l'ai découvert et trouvé une solution de contournement. Articles précédents sur le ralentissement de Windows:


Quelque chose ne va pas


Je ne cherche pas de problèmes, mais je pense que je les ai trouvés. Peut-être parce que je récupère Chrome des sources des centaines de fois au cours du week-end, ou que je n'ai pas de chance dans la vie. Je suppose que nous ne le saurons jamais. D'une manière ou d'une autre, cet article décrit le cinquième problème grave que j'ai rencontré dans Windows lors de la création de Chrome.

  1. Sérialisation non planifiée, ce qui conduit à une interface utilisateur de blocage complète: "Processeur 24 cœurs, mais je ne peux pas déplacer le curseur . "
  2. Une fuite de descripteur de processus dans l'un des modules complémentaires de Microsoft pour Windows: «Les processus zombies mangent votre mémoire» .
  3. Une erreur de correction de longue date dans le cache de fichiers Windows: «Erreur du compilateur? Erreur de l'éditeur de liens? Bogue du noyau Windows. "
  4. Échec des performances lors de l'utilisation incorrecte des notifications de fichiers: «Ralentissement de Windows, partie 1: accès aux fichiers» .
  5. Et ceci: une étrange solution architecturale qui ralentit la création de processus au fil du temps.

Suivi des accidents rares


Les ordinateurs doivent être fiables et prévisibles, et quelque chose d'autre m'ennuie. Si je crée Chrome plusieurs centaines de fois de suite, j'aimerais que chaque assemblage réussisse. Par conséquent, lorsque notre processus de compilation distribuée (gomacc.exe) se bloque parfois, je souhaite enquêter sur cela. J'ai configuré l'enregistrement automatique des vidages sur incident , donc je vois que des plantages se produisent lorsqu'une corruption de tas est détectée. Un moyen simple de vérifier consiste à activer le segment de page afin que le segment de mémoire Windows place chaque allocation de mémoire sur une page distincte. Cela signifie que l'utilisation après libération et les débordements de tampon provoquent une défaillance instantanée au lieu de dommages difficiles à diagnostiquer. J'ai déjà écrit sur l' activation de pageheap en utilisant App Verifier .

App Verifier ralentit le programme pour deux raisons: les allocations de mémoire sont ralenties et les allocations alignées sur les pages désactivent pratiquement le cache du processeur. Ainsi, un léger ralentissement de l'assemblage était prévisible, et c'est arrivé.

Mais quand je suis arrivé plus tard, l'assemblée a semblé s'arrêter complètement. Après environ 7 000 étapes d'assemblage , aucun progrès n'a été observé.

O (n ^ 2) n'est généralement pas bon


Il s'avère que Application Verifier aime créer des fichiers journaux. Et peu importe que personne ne regarde ces fichiers, il les crée au cas où. Et ces fichiers doivent avoir des noms uniques. Je suis sûr que cela semblait être une bonne idée de simplement donner aux journaux des noms numériques dans l'ordre croissant, tels que gomacc.exe.0.dat, gomacc.exe.1.dat, etc.

Pour obtenir des noms numériques dans l'ordre croissant, vous devez déterminer le numéro à utiliser ensuite. Le moyen le plus simple consiste à essayer les noms / numéros possibles jusqu'à ce que vous en trouviez un qui n'a pas encore été utilisé. Autrement dit, essayez de créer un nouveau fichier appelé gomacc.exe.0.dat, et s'il existe déjà, essayez gomacc.exe.1.dat et ainsi de suite.

Qu'est-ce qui pourrait mal tourner?

En fait, dans le pire des cas, tout est plutôt mauvais


Il s'avère que si vous effectuez une recherche linéaire d'un nom de fichier inutilisé lors de la création d'un processus, le démarrage de N processus nécessite O (N ^ 2) opérations. Le bon sens veut que les algorithmes O (N ^ 2) soient trop lents si vous ne pouvez pas garantir que N reste toujours relativement petit.

La gravité de la situation dépend du temps qu'il faut pour vérifier l'existence du fichier. J'ai pris des mesures et constaté que sur Windows, cela prend environ 80 microsecondes (80 μs ou 0,08 ms). Le démarrage du premier processus est rapide, mais le démarrage du 1000e processus nécessite l'analyse de 1000 fichiers journaux déjà créés. Cela prend 80 ms, puis plus.

Une version typique de Chrome nécessite que le compilateur s'exécute environ 30 000 fois. Chaque exécution du compilateur nécessite l'analyse de N fichiers journaux créés précédemment, 0,08 ms pour vérifier chaque fichier. Une recherche linéaire du prochain nom de fichier journal disponible signifie que l'exécution de N processus nécessite (N ^ 2) / 2 vérifie l'existence du fichier, c'est-à-dire 30000 * 30000/2, soit 450 millions. Étant donné que chaque vérification de l'existence d'un fichier prend 0,08 ms, cela représente 36 millions de millisecondes, soit 36 ​​000 secondes. Autrement dit, le temps de construction de Chrome, qui est généralement de cinq à dix minutes, augmentera de dix heures supplémentaires.

Merde.

En écrivant cet article, j'ai reproduit l'erreur en exécutant un fichier exécutable vide environ 7000 fois - et j'ai vu une courbe O (n ^ 2) claire comme ceci:



Curieusement, si nous prenons la trace ETW et regardons le temps d'appel moyen à CreateFile, alors pour presque tous les fichiers, le résultat est inférieur à cinq microsecondes (une moyenne de 4,386 μs dans l'exemple ci-dessous):



Il semble que cela montre uniquement la restriction ETW sur le suivi des E / S de fichiers. Les événements d'E / S de fichiers suivent uniquement le niveau le plus bas du système de fichiers, et au-dessus de Ntfs.sys, il existe de nombreux autres niveaux, notamment FLTMGR.SYS et ntoskrnl.exe. Cependant, le ralentissement ne peut pas être complètement masqué - l'utilisation du processeur est visible sur le graphique d'utilisation du processeur. La capture d'écran ci-dessous montre l'intervalle de temps de 548 ms, ce qui représente la création d'un seul processus. Fondamentalement, tout le temps qu'il faut pour analyser environ 6850 noms de fichiers journaux possibles:



Un disque plus productif sera-t-il utile?


Non.

La quantité de données traitées est faible et la quantité d'écriture sur le disque est encore moindre. Lors de mes tests pour reproduire un bug, le disque était presque complètement inactif. Ce problème est lié au processeur car toutes les données de disque pertinentes sont mises en cache. Et même si les frais généraux étaient réduits d'un ordre de grandeur, ils seraient encore trop importants. Vous ne pouvez pas améliorer l'algorithme O (N ^ 2).

Découverte


Ce problème particulier peut être détecté en recherchant% userprofile% \ appverifierlogs pour les fichiers .dat. En général, vous pouvez détecter un ralentissement de la création de processus en examinant la trace ETW, et vous savez maintenant quoi rechercher.

Solution


La solution la plus simple consiste à désactiver la journalisation. Cela arrêtera également de remplir le disque avec des gigaoctets de journaux. Il est désactivé par la commande suivante:

appverif.exe -logtofile disable

Après avoir désactivé la journalisation, j'ai constaté que mes processus ont démarré environ trois fois plus vite (!) Qu'au début du test, et le ralentissement a complètement disparu. 7000 processus Application Verifier surveillés sont créés en 1,5 minute et non 40 minutes. Avec mon simple fichier batch pour les tests et un processus simple, je vois les vitesses de création de processus suivantes:

  • généralement 200 par seconde (5 ms par processus)
  • 75 par seconde avec Application Verifier activé mais la journalisation désactivée (13 ms par processus)
  • 40 par seconde avec Application Verifier activé et la journalisation activée, dans un premier temps ... (25 ms par processus, le temps augmente progressivement à l'infini)
  • 0,4 par seconde après une version de Chrome

Microsoft peut résoudre ce problème en abandonnant l'augmentation monotone du nombre de fichiers journaux. S'ils utilisaient la date et l'heure actuelles comme nom de fichier (jusqu'à une milliseconde ou en résolution supérieure), ils obtiendraient des noms plus sémantiquement significatifs de journaux créés très rapidement sans pratiquement aucune logique de recherche pour un fichier unique.

Mais Application Verifier n'est plus pris en charge et les fichiers journaux sont de toute façon inutiles, il suffit donc de les désactiver.

Informations complémentaires


Des fichiers batch et un script pour recréer le bogue après avoir activé Application Verifier pour empty.exe se trouvent ici .

La trace ETW vers la fin de l'expérience est ici .

Autres liens:

Données de synchronisation brutes utilisées pour créer un graphique.

Discussion sur Reddit

Discussion chez Hacker News

Pour des exemples d'autres algorithmes O (n ^ 2) qui colportent, voir Accidentally Quadratic

Pour un plaisir plus banal, voir une compilation vidéo de mes 19 façons différentes de me rendre au travail en septembre - j'étais trop occupé pour continuer l'expérience ce mois-ci.

Source: https://habr.com/ru/post/fr427303/


All Articles