Como o Windows pode despejar a RAM completa no arquivo de hibernação tão rápido?


64

Eu estava lendo um artigo que explicava o procedimento de hibernação no Microsoft Windows. Os principais pontos que eu tirei disso são

  1. O Windows despeja toda a RAM (talvez depois de processada) no hiberfil.sysarquivo.
  2. Durante a inicialização, o arquivo de hibernação é lido e o conteúdo é carregado na RAM.

Minha pergunta é quando normalmente copio um arquivo de tamanho, digamos, 1 GB, leva cerca de 2 minutos para ser concluído.

No entanto, quando o Windows está gravando o arquivo de hibernação (durante o procedimento de hibernação), todo o processo leva cerca de 10 a 15 segundos. Por que existe tanta diferença na velocidade de gravação?

O tamanho da minha RAM é de 4 GB. (Não estou falando sobre tecnologia de inicialização rápida.)

Benchmarks:

  1. Copiando arquivo de 1 GB do Disco 1 para o Disco 2 (externo): 2,3 minutos.
  2. Hibernando o sistema: 15 segundos.

3
Não sei a resposta, mas aposto que se você verificou o livro Windows Internals "Capítulo 13: Inicialização e desligamento", ele diria a você (se eu tivesse o livro, verificaria).
Scott Chamberlain

2
Essa é uma boa pergunta. Quando a hibernação foi implementada pela primeira vez em 1998, não foi tão rápida.
Gabe

22
@ codificador: o sistema NT assegura que o hyberfil.sys tenha todo o espaço alocado e que o arquivo inteiro não esteja fragmentado. Nessa condição, não há saltos de cabeça no disco rígido durante a operação. Então você terá velocidades efetivas como 150Mo / s. Você pode verificar novamente o que eu disse fsutil.
precisa saber é o seguinte

3
O disco externo também costuma ser mais lento que o disco interno.
Harry Johnston #

2
@ EricLippert - certamente não armazena toda a RAM, mas isso ainda não explica. Normalmente, tenho poucos gigabytes de RAM ativa que precisam ser armazenados (VS2013 ou Eclipse + mais algumas coisas exigem muita memória RAM) e eles são armazenados na velocidade que me parece maior do que a velocidade de gravação teórica do meu SSD não-SSD dirigir.
Davor

Respostas:


45

Esta é provavelmente uma resposta tripla.

Uma coisa que pode estar em jogo aqui é o novo Hybrid Shutdown no Windows, que efetivamente fecha seus aplicativos, efetua o logoff e depois passa a hibernar o núcleo do sistema operacional. Já ter esses dados salvos significa que eles não precisam "re-hibernar" potencialmente.

A segunda coisa seria que a hibernação não precisaria salvar páginas de memória que são paginadas para o arquivo de troca ou não estão em uso (esse seria um motivo para preencher agressivamente o arquivo de troca e manter os dados na memória) .

A terceira seria que os dados do arquivo de hibernação também são compactados . Combine isso com o meu segundo ponto e, se você tiver apenas um pequeno conjunto de dados a exportar que contém dados altamente compactáveis ​​(os executáveis ​​geralmente são compactados bem), a quantidade de dados a serem enviados para o arquivo de hibernação pode ser substancialmente menor que o conjunto de trabalho De dados. Observe que, conforme declarado nos comentários, os caches de arquivos e outros dados desnecessários do buffer podem ser facilmente descartados sem causar efeitos negativos para reduzir a quantidade de dados a serem despejados no arquivo de hibernação.

Além disso, os discos rígidos atuais são bastante rápidos. Com um disco com gravação sustentada na ordem de 100 MB / s, você poderá gravar (não compactado) 4 GB de RAM em menos de um minuto. Como a hibernação pode ser feita como a última coisa depois de suspender todos os processos do usuário e antes de suspender a CPU, o SO geralmente terá a velocidade total de gravação do disco. Isso é algo que seu benchmark simples não terá, e copiar de disco para disco será potencialmente mais lento do que simplesmente gravar RAM em disco.

Combine essas coisas e a quantidade de dados a serem gravados no arquivo de hibernação pode ser bem pequena, potencialmente da ordem de 1 GB e provavelmente seria gravada em um grande bloco contínuo em menos de 10 segundos.


37
Ou, para deixar mais claro: sua RAM provavelmente não está cheia. Os buffers são liberados e o cache é descartado na hibernação. Somente a memória realmente usada pelos aplicativos deve ser gravada no disco. O desligamento híbrido reduz a quantidade de memória em uso desconectando o usuário.
Daniel B

2
Páginas que não estão sujas é uma declaração mais geral de "paginado para o arquivo de troca", isso inclui executáveis. (Como os executáveis ​​estão um pouco fragmentados no disco, isso pode retardar a ativação.) Além disso, os buffers de arquivos limpos podem presumivelmente ser descartados, mesmo que não façam parte de um arquivo mapeado na memória.
Paul A. Clayton

3
@ user2284570 do documento vinculado nessa resposta "O Windows suporta a hibernação, copiando o conteúdo da memória para o disco. O sistema compacta o conteúdo da memória antes de preservá-lo no disco, o que reduz o espaço em disco necessário para menos do que a quantidade total de memória física no sistema. "
Mokubai

4
@ user2284570: Isso porque o pior cenário é a compactação 1: 1. O Windows precisa garantir que haja espaço (reservado) suficiente no hyberfil.sys para qualquer configuração de memória possível - mesmo que seja necessário apenas um décimo do tamanho da RAM para uma hibernação específica. Acrescente a isso que uma parte decente do uso da RAM são arquivos carregados na memória (executáveis, recursos ...), mas ainda mapeados a partir do HDD, e você pode realmente economizar bastante gravação. Faça com que um programa gere 4 GiB de dados cripto-aleatórios na RAM, e a hibernação leva muito mais tempo - e mesmo assim, alguns deles podem estar em troca.
Luaan 11/03/2015

3
@ user2284570: O arquivo é muito grande para garantir que haja espaço no disco para armazenar toda a memória. Nem todo esse espaço é realmente usado na hibernação. Às vezes, o arquivo será (digamos) 7% do conteúdo da memória compactada, 93% de lixo eletrônico.
psmears 11/03/2015

31

Primeiro, a quantidade de RAM que precisa ser salva é surpreendentemente pequena. De fato, apenas o conjunto de páginas sujas mapeadas ("write-back lento") precisa ser liberado, assim como todas as páginas particulares que foram gravadas e o código executável realocado precisam ser gravadas.

  • Os segmentos .text dos executáveis ​​são sempre apoiados pelo mapeamento de arquivos. Isso também é verdade para pelo menos algumas DLLs (mas não todas, depende se elas precisam ser realocadas).
  • A memória que é apoiada de maneira semelhante por mapeamentos de arquivos pode ser descartada (presume-se que não seja CoW ou RW e esteja sujo).
  • O write-back preguiçoso ainda precisará ocorrer, mas, além disso, os caches podem ser descartados.
  • A memória alocada, mas não gravada (geralmente a maior parte dos dados do aplicativo!) É suportada pela página zero e pode ser descartada.
  • A maior parte das páginas de memória que estão no status "em espera" (o conjunto de trabalho real por processo residente no Windows é surpreendentemente pequeno, meros 16 MB) será copiado para o arquivo de paginação em segundo plano em algum momento e poderá ser descartado .
  • Regiões da memória mapeadas por determinados dispositivos, como a placa gráfica, podem (possivelmente) não precisar ser salvas. Às vezes, os usuários ficam surpresos ao conectar 8GiB ou 16GiB a um computador, e 1GiB ou 2GiB simplesmente "desaparecem" sem motivo aparente. As principais APIs gráficas exigem que os aplicativos possam tornar o conteúdo do buffer inválido "sob algumas condições" (sem dizer exatamente o que isso significa). Portanto, não é irracional esperar que a memória fixada pelo driver gráfico também seja descartada. Afinal, a tela ficará escura de qualquer maneira.

Segundo, ao contrário de você copiar um arquivo, despejar o conjunto de páginas de RAM que precisam ser salvas em disco é uma única gravação sequencial e contígua do ponto de vista da unidade. A API do Win32 até expõe uma função no nível do usuário para essa mesma operação. O Gather Write é suportado diretamente pelo hardware e funciona tão rápido quanto o disco é capaz de aceitar dados fisicamente (o controlador extrai dados diretamente via DMA).
Existem várias condições prévias para que isso funcione (como alinhamento, tamanho do bloco, fixação), e ele não funciona bem com o armazenamento em cache e não existe "write-back lento" (que é uma otimização muito desejável em operação normal) )
Essa é a razão pela qual nem toda gravaçãofunciona assim o tempo todo. No entanto, quando o sistema está salvando o arquivo de hibernação, todas as pré-condições são atendidas automaticamente (todos os dados são alinhados, dimensionados e fixados) e o armazenamento em cache tornou-se irrelevante porque o computador será desligado em um momento.

Terceiro, fazer uma única gravação contígua é muito favorável tanto para discos giratórios quanto para discos de estado sólido.

O arquivo de troca e o arquivo de hibernação são geralmente alguns dos arquivos mais antigos criados e reservados no disco. Eles geralmente têm um, no máximo dois fragmentos. Portanto, a menos que os setores estejam danificados e o disco precise realocar os setores físicos, uma gravação sequencial lógica será convertida em uma gravação sequencial física em um disco rotativo.

Nenhuma operação de leitura-modificação-gravação é necessária no disco quando uma grande quantidade de dados sequenciais e contíguos está sendo gravada. Esse problema é menos pronunciado em discos rígidos giratórios, que podem gravar setores únicos muito pequenos (desde que você não grave bytes únicos, o que o cache geralmente impede, o dispositivo não precisará buscar o conteúdo original e gravar a versão modificada). .
Isso é, no entanto, algo que é muito perceptível no SSD, onde cada gravação significa que, por exemplo, um bloco de 512kB (que é um número usual, mas pode ser maior) deve ser lido e modificado pelo controlador e gravado em um arquivo diferente. quadra. Embora você possa, em princípio, escrever para (mas não substituir)) unidades menores em discos flash, você só pode apagar blocos enormes, é assim que o hardware funciona. Essa é a razão pela qual os SSDs se saem muito melhor em gravações sequenciais enormes.


Mesmo se uma DLL for realocada, a única coisa necessária para trazê-la de volta é o endereço realocado. A realocação é um processo determinístico e pode ser repetido.
MSalters

"Reunir escrever"? Você quer dizer "Em vez disso, escreva"?
Peter Mortensen

3
@ PeterMortensen: Não, eu realmente quero dizer coletar e escrever (em oposição à leitura dispersa). Isso significa gravar em um único arquivo enquanto coleta os dados de vários locais. Você fornece uma matriz de estruturas, cada uma das quais contém um endereço inicial e um comprimento (com requisitos rigorosos de alinhamento). O sistema operacional os passa para o controlador e o hardware faz o resto.
Damon

1
@MSalters: Mas a realocação cria uma cópia privada da página e, em seguida, é extremamente difícil determinar se alguma outra modificação foi feita na cópia privada. Compare com os mapeamentos que não precisaram de correção e use a cópia na gravação. Se outras modificações forem feitas, haverá uma cópia privada. Caso contrário, a página ainda será configurada para CoW.
Ben Voigt

1
@MSalters Pode ser um processo determinístico, mas isso não implica que o código de hibernação opere na mesma camada da pilha de software que o vinculador. Se a hibernação estiver na camada do kernel e o link estiver na camada do usuário, a hibernação não poderá fazer nenhuma suposição sobre o que o vinculador faz.
kasperd

10

Não despeja toda a RAM em tempo de hibernação.

Já terá uma grande parte da RAM já duplicada no disco. Isso não apenas permite que a hibernação aconteça rapidamente, mas também permite que a memória seja disponibilizada rapidamente para novos programas (para que eles possam iniciar rapidamente).

Portanto, ele só precisa escrever uma pequena fração dos 4 GB e isso pode ser feito em 10 a 15s.

Da microsoft :

Quando a RAM é escassa (por exemplo, bytes confirmados é maior que a RAM instalada), o sistema operacional tenta manter uma certa fração da RAM instalada disponível para uso imediato, copiando as páginas de memória virtual que não estão em uso ativo no arquivo de paginação . Portanto, esse contador não chegará a zero e não é necessariamente uma boa indicação se o seu sistema está com pouca memória RAM.


2

Além de todos os itens acima, acho que existem outros fatores em jogo.

Uma é que, ao copiar um arquivo, o arquivo deve ser lido e gravado; a hibernação requer apenas que o arquivo seja gravado. Já está, por definição, na memória!

Intimamente relacionado a isso, ao ler um arquivo e gravá-lo ao mesmo tempo, para economizar memória, o processo é: ler um pedaço, escrever um pedaço, atualizar o diretório (para mostrar o novo tamanho); leia um pedaço, escreva um pedaço, atualize o diretório.

Cada vez que você move de uma parte do disco para outra (por exemplo, leia o arquivo a para gravar o arquivo b, escreva o arquivo b para escrever o diretório e escreva o diretório para ler o próximo bloco), o disco deve procurar - mover as cabeças, deixe as cabeças assentarem, aguarde a parte certa do disco. Essa é uma das vantagens de um disco de estado sólido - a busca não leva tempo. Ao hibernar, os dados são gravados de ponta a ponta. O arquivo de hibernação (troca) é pré-alocado, portanto, o diretório não precisa ser atualizado (você não está alterando o tamanho do arquivo de hibernação, apenas o conteúdo).

E, finalmente, seu computador suspendeu todas as outras tarefas - é a ÚNICA coisa que ele está fazendo (duvido que isso faça muita diferença, mas certamente fará algumas!). Até coisas como gerenciamento de memória e alternância de tarefas estão suspensas.


É obrigado a fazer uma enorme diferença!
Leveza raças na órbita

@LightnessRacesinOrbit: a contenção da CPU quase não fará diferença alguma. A falta de contenção de E / S é importante, mas essa resposta já afirmou que a busca diminui o desempenho e a busca, e não a falta de largura de banda geral, é o principal problema da contenção de E / S.
Ben Voigt

@BenVoigt: Sim, eu concordo. E quando você tem 40 processos, todos tentando fazer coisas no disco, isso aumentará substancialmente a busca por disco. (tl; dr eu não estava falando de contenção de CPU)
Leveza raças na órbita

@ LightnessRacesinOrbit: Isso parece ... incomum mesmo durante a operação normal (tudo, exceto entrar e sair da hibernação). Sei que quando pego uma tarefa em segundo plano atingindo o disco, desinstalo o otário e o substituo por algo que só acessa o disco quando solicito algo.
Ben Voigt

@BenVoigt: Isso parece improvável. O registro de daemon é o contra-exemplo mais óbvio, seguido por atualizações de arquivos de deriva do ntpd. Não estou afirmando que nenhum desses exemplos tenha um grande efeito aqui, mas não acho razoável esperar que nenhuma tarefa em segundo plano toque o disco autonomamente.
Lightness Races em Órbita

0

Provavelmente, isso ocorre porque a RAM possui velocidades de entrada / saída muito mais rápidas que o disco rígido, para que a RAM possa produzir as coisas nele tão rapidamente quanto o disco rígido pode ler.

Ao copiar arquivos, você também é limitado por vários fatores - a velocidade do disco, se for necessário ler e sair no mesmo disco, levará mais tempo, a velocidade limitada da conexão (se for para a unidade externa), verificando-a não está substituindo nada etc


9
mas ainda precisa de OS para gravar os dados de 4GB de RAM no disco que é governada pelo I / O gargalo
codificador

Também assumindo parâmetros favoráveis, implica que durante a hibernação, a velocidade de gravação do meu disco passa de 40 MB / s para ~ 260 MB / s. Pode ser o correto?
Codificador

1
Provavelmente - não deve haver muito gargalo de E / S, pois ele só precisa gravar os dados (provavelmente existe algo no lugar para que ele não substitua as coisas e onde colocar os dados para que não precisa ler muito o disco). No meu laptop (linux dual boot) eu posso usar dd if=/dev/zero of=/tmp/output.img bs=8k count=256ke obter 1862606848 bytes (1.9 GB) copied, 1.81605 s, 1.0 GB/s, então parece possível (acrescentarei que a cópia de arquivos do Windows parece demorar desnecessariamente).
Wilf

Você também pode obter uma transferência muito mais rápida ao copiar arquivos pela Internet local. Além disso, pode não ser necessário copiar todo o material da RAM - alguns dados na RAM podem ser armazenados em cache e não são necessários para restaurar o sistema ao sair da hibernação.
Wilf

Eu apenas tentei o benchmark dd no meu sistema. Ele nunca ultrapassou 52 MB / s: / (máquina antiga) No entanto, acredito que "provavelmente existe algo no local para que ele não substitua as coisas e onde colocar os dados para que não precise ler o disco muito " É a chave para a velocidade rápida.
Codificador
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.