Abrandando o Windows Parte 2: Criando processos



O Windows tem sido responsabilizado pela lentidão das operações de arquivo e pela criação de processos. Você já tentou torná-los ainda mais lentos? Este artigo mostrará a técnica de como desacelerar gradualmente a criação de processos no Windows (ad infinitum) invisivelmente para a maioria dos usuários!

E, claro, o artigo também mostrará como detectar e evitar esse problema.

Esse é um problema real que encontrei no início do ano, e o artigo explica como descobri e encontrei uma solução alternativa. Artigos anteriores sobre como diminuir a velocidade do Windows:


Algo está errado


Não estou procurando problemas, mas acho que os encontrei. Talvez porque eu colecione o Chrome da fonte centenas de vezes no fim de semana ou tenha azar na vida. Acho que nunca saberemos. De uma forma ou de outra, este artigo descreve o quinto problema sério que encontrei no Windows ao criar o Chrome.

  1. Serialização não planejada, o que leva a uma interface de usuário travada completa: "Processador de 24 núcleos, mas não consigo mover o cursor" .
  2. Um descritor de processo vazou em um dos complementos da Microsoft para Windows: "Os processos zumbis consomem sua memória" .
  3. Um erro de correção de longa data no cache de arquivos do Windows: “Erro do compilador? Erro do vinculador? Bug no kernel do Windows ".
  4. Falha no desempenho ao usar as notificações de arquivo incorretamente: "Abrandando o Windows, Parte 1: acesso ao arquivo" .
  5. E isso: uma solução arquitetônica estranha que diminui a criação de processos ao longo do tempo.

Rastreamento raro de acidentes


Os computadores devem ser confiáveis ​​e previsíveis, e algo mais me incomoda. Se eu criar o Chrome várias centenas de vezes seguidas, gostaria que todas as montagens fossem bem-sucedidas. Portanto, quando nosso processo de compilação distribuído (gomacc.exe) às vezes falha, desejo investigar isso. Eu configurei a gravação automática de despejos de memória , então vejo que ocorrem quando a corrupção da pilha é detectada. Uma maneira fácil de verificar é habilitar o heap de página para que o heap do Windows coloque cada alocação de memória em uma página separada. Isso significa que o uso após liberação e os estouros de buffer causam uma falha instantânea em vez de danos difíceis de diagnosticar. Eu escrevi anteriormente sobre como ativar o pageheap usando o App Verifier .

O App Verifier diminui a velocidade do programa por dois motivos: as alocações de memória são mais lentas e as alocações alinhadas à página praticamente desativam o cache do processador. Assim, uma ligeira desaceleração na montagem era previsível, e aconteceu.

Mas quando cheguei mais tarde, a assembléia pareceu parar completamente. Após cerca de 7000 etapas de montagem , nenhum progresso foi perceptível.

O (n ^ 2) geralmente não é bom


Acontece que o Application Verifier gosta de criar arquivos de log. E não importa que ninguém esteja assistindo esses arquivos, ele os cria apenas por precaução. E esses arquivos devem ter nomes exclusivos. Tenho certeza que pareceu uma boa idéia fornecer apenas os nomes numéricos dos logs em ordem crescente, como gomacc.exe.0.dat, gomacc.exe.1.dat e assim por diante.

Para obter nomes numéricos em ordem crescente, você precisa determinar qual número usar em seguida. A maneira mais fácil é experimentar possíveis nomes / números até encontrar um que ainda não tenha sido usado. Ou seja, tente criar um novo arquivo chamado gomacc.exe.0.dat e, se ele já existir, tente gomacc.exe.1.dat e assim por diante.

O que poderia dar errado?

De fato, no pior dos casos, tudo é muito ruim


Acontece que, se você executar uma pesquisa linear por um nome de arquivo não utilizado ao criar um processo, iniciar N processos executará operações O (N ^ 2) . O senso comum determina que os algoritmos O (N ^ 2) sejam muito lentos se você não puder garantir que N sempre seja relativamente pequeno.

A gravidade da situação depende de quanto tempo leva para verificar a existência do arquivo. Fiz medições e descobri que no Windows leva cerca de 80 microssegundos (80 μs ou 0,08 ms). O início do primeiro processo é rápido, mas o 1000º processo requer a verificação de 1000 arquivos de log já criados. Leva 80 ms e depois ainda mais.

Uma compilação típica do Chrome exige que o compilador execute cerca de 30.000 vezes. Cada execução do compilador requer a verificação de N arquivos de log criados anteriormente, 0,08 ms para verificar cada arquivo. Uma pesquisa linear para o próximo nome de arquivo de log disponível significa que a execução de N processos requer (N ^ 2) / 2 verificações da existência do arquivo, ou seja, 30.000 * 30.000 / 2, que são 450 milhões. Como cada verificação da existência de um arquivo leva 0,08 ms, são 36 milhões de milissegundos ou 36.000 segundos. Ou seja, o tempo de compilação do Chrome, que geralmente é de cinco a dez minutos, aumentará em mais dez horas.

Droga.

Ao escrever este artigo, reproduzi o erro executando um arquivo executável vazio cerca de 7000 vezes - e vi uma curva O (n ^ 2) clara como esta:



Curiosamente, se pegarmos o rastreamento ETW e observarmos o tempo médio de chamada para CreateFile, em quase todos os arquivos o resultado será menor que cinco microssegundos (uma média de 4,386 μs no exemplo abaixo):



Parece que isso mostra apenas a restrição ETW no rastreamento de E / S do arquivo. Os eventos de E / S de arquivo rastreiam apenas o nível mais baixo do sistema de arquivos e, acima do Ntfs.sys, existem muitos outros níveis, incluindo FLTMGR.SYS e ntoskrnl.exe. No entanto, a desaceleração não pode ser completamente oculta - o uso da CPU é visível no gráfico Uso da CPU. A captura de tela abaixo mostra o intervalo de tempo de 548 ms, o que representa a criação de um único processo. Basicamente, todo o tempo necessário para verificar cerca de 6850 possíveis nomes de arquivos de log:



Um disco mais produtivo ajudará?


Não.

A quantidade de dados processados ​​é pequena e a quantidade de gravação no disco é ainda menor. Durante meus testes para reproduzir um bug, o disco estava quase completamente ocioso. Esse problema está relacionado à CPU porque todos os dados relevantes do disco são armazenados em cache. E mesmo que os custos indiretos fossem reduzidos em uma ordem de magnitude, eles ainda seriam muito grandes. Você não pode melhorar o algoritmo O (N ^ 2).

Descoberta


Esse problema específico pode ser detectado pesquisando% userprofile% \ appverifierlogs em busca de arquivos .dat. Em geral, é possível detectar uma desaceleração na criação do processo examinando o rastreio ETW e agora você sabe o que procurar.

Solução


A solução mais fácil é desativar o log. Isso também irá parar de encher o disco com gigabytes de logs. Está desativado pelo seguinte comando:

appverif.exe -logtofile disable

Depois de desativar o log, descobri que meus processos começaram três vezes mais rápido (!) Do que no início do teste, e a desaceleração desapareceu completamente. Os processos 7000 Application Verifier monitorados são criados em 1,5 minutos, não em 40 minutos. Com meu arquivo em lote simples para testes e um processo simples, vejo as seguintes velocidades de criação de processo:

  • tipicamente 200 por segundo (5 ms por processo)
  • 75 por segundo com o Application Verifier ativado, mas o log desativado (13 ms por processo)
  • 40 por segundo com o Application Verifier ativado e o log ativado, no início ... (25 ms por processo, o tempo aumenta gradualmente até o infinito)
  • 0,4 por segundo após uma compilação do Chrome

A Microsoft pode corrigir esse problema abandonando o aumento monótono no número de arquivos de log. Se eles usassem a data e a hora atuais como um nome de arquivo (até um milissegundo ou em resolução mais alta), obteriam nomes semanticamente mais significativos dos logs criados muito rapidamente, praticamente sem lógica de pesquisa para um arquivo exclusivo.

Mas o Application Verifier não é mais suportado e os arquivos de log são inúteis de qualquer maneira, então apenas desative-os.

Informações de suporte


Arquivos em lote e um script para recriar o bug depois de ativar o Application Verifier para empty.exe podem ser encontrados aqui .

O rastreamento ETW do final do experimento está aqui .

Outros links:

Dados brutos de tempo usados ​​para criar um gráfico.

Discussão no Reddit

Discussão em Hacker News

Para exemplos de outros algoritmos O (n ^ 2) que estão sendo distribuídos, consulte Acidentalmente Quadrático

Para uma diversão mais mundana, veja uma compilação em vídeo das minhas 19 maneiras diferentes de começar a trabalhar em setembro - eu estava muito ocupado para continuar o experimento este mês.

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


All Articles