Jak system Windows może tak szybko zrzucić całą pamięć RAM w pliku hibernacji?

64

Przeglądałem artykuł wyjaśniający procedurę hibernacji w systemie Microsoft Windows. Główne punkty, które z tego wyciągam, to:

  1. Windows zrzuca całą pamięć RAM (może po przetworzeniu) do hiberfil.syspliku.
  2. Podczas rozruchu plik hibernacji jest odczytywany, a zawartość jest ładowana do pamięci RAM.

Moje pytanie brzmi: kiedy zwykle kopiuję plik o rozmiarze, powiedzmy 1 GB, jego ukończenie zajmuje około 2 minut .

Jednak gdy system Windows zapisuje plik hibernacji (podczas procedury hibernacji), cały proces może potrwać 10–15 sekund. Dlaczego jest taka różnica w szybkości pisania?

Mój rozmiar RAM to 4 GB. (Nie mówię o technologii szybkiego rozruchu.)

Benchmarki:

  1. Kopiowanie pliku 1 GB z dysku 1 na dysk 2 (zewnętrzny): 2,3 minuty.
  2. Hibernacja systemu: 15 sekund.
koder
źródło
3
Nie znam odpowiedzi, ale założę się, że jeśli sprawdziłeś książkę Windows Wewnętrzne „Rozdział 13: Uruchomienie i zamknięcie”, to by ci to powiedział (gdybym sam miał książkę, sprawdziłbym).
Scott Chamberlain,
2
To dobre pytanie. Kiedy hibernacja została wdrożona w 1998 roku, nie była tak szybka.
Gabe
22
@ koder: w systemie NT upewnij się, że hyberfil.sys ma przydzielone pełne miejsce i że cały plik nie jest pofragmentowany. W tym stanie podczas operacji nie dochodzi do skoków głowy na dysk twardy. Otrzymasz efektywne prędkości, takie jak 150Mo / s. Możesz ponownie sprawdzić, co powiedziałem fsutil.
user2284570,
3
Dysk zewnętrzny jest zwykle wolniejszy niż dysk wewnętrzny.
Harry Johnston,
2
@EricLippert - z pewnością nie przechowuje całej pamięci RAM, ale to wciąż tego nie wyjaśnia. Regularnie mam kilka gigabajtów aktywnej pamięci RAM, którą należy przechowywać (VS2013 lub Eclipse + kilka innych rzeczy wymaga dużo pamięci RAM), i są one przechowywane z prędkością, która wydaje mi się większa niż nawet teoretyczna prędkość zapisu mojego non-SSD napęd.
Davor

Odpowiedzi:

45

To prawdopodobnie trzykrotna odpowiedź.

Jedną z rzeczy, które mogą tu być odtwarzane, jest nowy system Hybrid Shutdown w systemie Windows, który skutecznie zamyka aplikacje, wylogowuje, a następnie przechodzi w stan hibernacji rdzenia systemu operacyjnego. Już zapisanie tych danych oznaczałoby, że nie trzeba „ponownie hibernować” ich potencjalnie.

Drugą rzeczą byłoby to, że hibernacja nie musiałaby zapisywać stron pamięci, które albo są stronicowane do pliku wymiany, albo nie są w użyciu (byłby to jeden z powodów agresywnego wypełnienia pliku wymiany i przechowywania danych również w pamięci) .

Trzecim byłoby skompresowanie danych pliku hibernacji . Połącz to z moim drugim punktem, a jeśli masz tylko mały zestaw danych do wyeksportowania, który zawiera wysoce kompresowalne dane (pliki wykonywalne są ogólnie dobrze skompresowane), wówczas ilość danych, które mają zostać przesłane do pliku hibernacji, może być znacznie mniejsza niż zestaw roboczy danych. Należy zauważyć, że, jak stwierdzono w komentarzach, pamięci podręczne plików i inne niepotrzebne dane bufora można łatwo usunąć bez negatywnego wpływu, aby zmniejszyć ilość danych, które należy zrzucić do pliku hibernacji.

Ponadto obecne dyski twarde są dość szybkie. Z dyskiem, który ma ciągły zapis rzędu 100 MB / s, będziesz mógł wypisać (nieskompresowane) 4 GB pamięci RAM w mniej niż minutę. Ponieważ hibernację można wykonać jako ostatnią rzecz po zawieszeniu wszystkich procesów użytkownika i przed zawieszeniem procesora, system operacyjny będzie na ogół miał pełną prędkość zapisu na dysku. Jest to jedna rzecz, której nie będzie miał Twój prosty test porównawczy, a kopiowanie z dysku na dysk będzie potencjalnie wolniejsze niż zwykłe zapisywanie pamięci RAM na dysku.

Połącz te rzeczy, a ilość danych, które zostaną zapisane w pliku hibernacji, może być dość mała, potencjalnie rzędu 1 GB i prawdopodobnie zostanie zapisana w jednym dużym ciągłym bloku w niecałe 10 sekund.

Mokubai
źródło
37
Lub, aby było bardziej jasne: Twoja pamięć RAM prawdopodobnie nie jest pełna. Bufory są opróżniane, a pamięć podręczna jest odrzucana po hibernacji. Tylko pamięć faktycznie używana przez aplikacje musi zostać zapisana na dysk. Hybrydowe zamknięcie zmniejsza ilość używanej pamięci poprzez wylogowanie użytkownika.
Daniel B
2
Strony, które nie są brudne, to bardziej ogólne stwierdzenie „przeniesione do pliku wymiany”, w tym pliki wykonywalne. (Ponieważ pliki wykonywalne są nieco rozproszone na dysku, może to spowalniać budzenie). Ponadto czyste bufory plików można prawdopodobnie po prostu usunąć, nawet jeśli nie są częścią pliku odwzorowanego w pamięci.
Paul A. Clayton,
3
@ user2284570 z dokumentu, do którego link w tej odpowiedzi „Windows obsługuje hibernację poprzez kopiowanie zawartości pamięci na dysk. System kompresuje zawartość pamięci przed zachowaniem jej na dysku, co zmniejsza wymaganą ilość miejsca na dysku do całkowitej ilości pamięci fizycznej w systemie. ”
Mokubai
4
@ user2284570: To dlatego, że najgorszym scenariuszem jest kompresja 1: 1. System Windows musi upewnić się, że w hyberfil.sys jest wystarczająca ilość (zarezerwowana) miejsca na każdą możliwą konfigurację pamięci - nawet jeśli potrzebuje tylko jednej dziesiątej pamięci RAM do określonej hibernacji. Dodaj do tego, że przyzwoitą częścią pamięci RAM są pliki załadowane do pamięci (pliki wykonywalne, zasoby ...), ale wciąż zmapowane z dysku twardego, i rzeczywiście można zaoszczędzić dużo pisania. Niech program wygeneruje 4 GiB danych krypto-losowych w pamięci RAM, a hibernacja trwa znacznie dłużej - i nawet wtedy niektóre z nich mogły zostać zamienione.
Luaan,
3
@ user2284570: Plik jest tak duży, aby zapewnić miejsce na dysku do przechowywania całej pamięci. Nie cała ta przestrzeń jest faktycznie wykorzystywana w hibernacji. Czasami plik będzie (powiedzmy) 7% zawartości skompresowanej pamięci, 93% śmieci.
psmears,
31

Po pierwsze, ilość pamięci RAM, którą należy zapisać, jest zaskakująco mała. W rzeczywistości tylko zestaw zmapowanych brudnych stron („leniwe zapisywanie”) musi zostać wyczyszczony, a także wszystkie prywatne strony, które zostały zapisane i przeniesiono kod wykonywalny.

  • Segmenty .text plików wykonywalnych są zawsze wspierane przez mapowanie plików. Dotyczy to również przynajmniej niektórych bibliotek DLL (ale nie wszystkich, zależy od tego, czy należy je przenieść).
  • Pamięć podobnie wspierana przez odwzorowania plików może zostać odrzucona (zakładając, że nie jest to CoW ani RW i jest brudna).
  • Leniwe zapisywanie nadal będzie musiało wystąpić, ale poza tym pamięci podręczne można odrzucić.
  • Pamięć, która została przydzielona, ​​ale do której nie została zapisana (zwykle większa część danych aplikacji!), Jest zabezpieczona zerową stroną i może zostać odrzucona.
  • Większa część stron pamięci, które są w stanie „gotowości” (faktyczny zestaw roboczy rezydenta na proces w systemie Windows jest zadziwiająco mały, zaledwie 16 MB) zostanie w pewnym momencie skopiowana do pliku strony w tle i może zostać odrzucona .
  • Regiony pamięci, które są mapowane przez niektóre urządzenia, takie jak karta graficzna, mogą (nie) wymagać zapisania. Użytkownicy są czasem zaskoczeni, że podłączają 8GiB lub 16GiB do komputera, a 1GiB lub 2GiB po prostu „zniknęły” bez wyraźnego powodu. Główne interfejsy API grafiki wymagają, aby aplikacje były w stanie unieważnić zawartość bufora „pod pewnymi warunkami” (bez dokładnego wyjaśnienia, co to oznacza). Dlatego nie jest nierozsądne oczekiwać, że pamięć przypięta przez sterownik karty graficznej również zostanie po prostu odrzucona. W końcu ekran i tak się ściemni.

Po drugie, w przeciwieństwie do kopiowania pliku, zrzut zestawu stron pamięci RAM, które należy zapisać na dysku, jest pojedynczym sekwencyjnym, ciągłym zapisem z punktu widzenia napędu. Win32 API nawet udostępnia funkcję poziomu użytkownika dla tej samej operacji. Zebranie zapisu jest bezpośrednio obsługiwane przez sprzęt i działa tak szybko, jak dysk jest fizycznie w stanie przyjąć dane (kontroler bezpośrednio pobierze dane przez DMA).
Jest wiele warunków wstępnych, aby to działało (takie jak wyrównanie, rozmiar bloku, przypinanie), i nie działa dobrze z buforowaniem i nie ma czegoś takiego jak „leniwy zapis zwrotny” (który jest bardzo pożądaną optymalizacją podczas normalnej pracy ).
To jest powód, dla którego nie każdy piszetak działa cały czas. Jednak gdy system zapisuje plik hibernacji, wszystkie warunki wstępne są spełnione automatycznie (wszystkie dane są wyrównane, mają rozmiar strony i są przypięte), a buforowanie stało się nieistotne, ponieważ komputer zostanie za chwilę wyłączony.

Po trzecie, wykonanie pojedynczego zapisu ciągłego jest bardzo korzystne zarówno dla dysków wirujących, jak i dysków półprzewodnikowych.

Plik wymiany i plik hibernacji są zwykle jednymi z najwcześniejszych plików utworzonych i zarezerwowanych na dysku. Zwykle mają jeden, najwyżej dwa fragmenty. Tak więc, chyba że sektory zostaną uszkodzone, a dysk nie będzie musiał ponownie przypisać sektorów fizycznych, logiczny zapis sekwencyjny przekłada się na fizyczny zapis sekwencyjny na wirującym dysku.

Żadne operacje odczytu-modyfikacji-zapisu nie są konieczne na dysku, gdy zapisywana jest ogromna ilość ciągłych, ciągłych danych. Ten problem jest mniej wyraźny na wirujących dyskach twardych, które mogą zapisywać pojedyncze sektory, które są dość małe (pod warunkiem, że nie zapisujesz pojedynczych bajtów, co zwykle zapobiega buforowaniu, urządzenie nie musi pobierać oryginalnej zawartości i zapisywać zmodyfikowanej wersji). .
Jest to jednak coś, co jest bardzo zauważalne na dysku SSD, gdzie każdy zapis oznacza, że ​​np. Blok 512 kB (który jest zwykłą liczbą, ale może być większy) musi zostać odczytany i zmodyfikowany przez kontroler i zapisany z powrotem do innego blok. Chociaż możesz w zasadzie pisać do (ale nie nadpisywać)) mniejsze jednostki na dyskach flash, zawsze możesz usunąć tylko ogromne bloki, tak działa sprzęt. To jest powód, dla którego dyski SSD radzą sobie o wiele lepiej w przypadku dużych zapisów sekwencyjnych.

Damon
źródło
Nawet jeśli biblioteka DLL zostanie przeniesiona, jedyną rzeczą potrzebną do jej przywrócenia jest przeniesiony adres. Przeniesienie jest procesem deterministycznym i można je powtórzyć.
MSalters
„Zbierz pisać”? Masz na myśli „Raczej pisz”?
Peter Mortensen,
3
@PeterMortensen: Nie, naprawdę mam na myśli zbieranie zapisu (w przeciwieństwie do odczytu rozproszonego). Oznacza to zapis do jednego pliku podczas zbierania danych z wielu lokalizacji. Podajesz tablicę struktur, z których każda zawiera adres początkowy i długość (z surowymi wymaganiami dotyczącymi wyrównania). System operacyjny przekazuje je do kontrolera, a sprzęt zajmuje się resztą.
Damon
1
@MSalters: Ale przeniesienie tworzy prywatną kopię strony, a następnie bardzo trudno jest ustalić, czy w kopii prywatnej wprowadzono jakiekolwiek inne modyfikacje. Porównaj z odwzorowaniami, które nie wymagały naprawy, i korzystaj z funkcji kopiowania przy zapisie. Jeśli zostaną wprowadzone inne modyfikacje, pojawi się kopia prywatna. Jeśli nie, strona będzie nadal skonfigurowana na CoW.
Ben Voigt,
1
@MSalters Może to być proces deterministyczny, ale nie oznacza to, że kod hibernacji działa na tej samej warstwie stosu oprogramowania, co linker. Jeśli hibernacja znajduje się w warstwie jądra, a łączenie jest warstwą użytkownika, to hibernacja nie może przyjmować żadnych założeń dotyczących działania linkera.
kasperd
10

W czasie hibernacji nie zrzuca całej pamięci RAM.

Będzie już miała dużą część pamięci RAM już zduplikowaną na dysku. Pozwala to nie tylko na szybką hibernację, ale także na szybkie udostępnienie pamięci dla nowych programów (dzięki czemu można je szybko uruchomić).

Dlatego musi napisać tylko niewielką część 4 GB i można to zrobić w 10-15 sekund.

Z Microsoft :

Gdy brakuje pamięci RAM (na przykład zatwierdzone bajty są większe niż zainstalowana pamięć RAM), system operacyjny będzie próbował zachować pewną część zainstalowanej pamięci RAM do natychmiastowego użycia, kopiując strony pamięci wirtualnej, które nie są aktywnie używane do pliku stronicowania . Dlatego ten licznik nie osiągnie zera i niekoniecznie jest dobrym wskaźnikiem tego, czy w twoim systemie brakuje pamięci RAM.

Peter Crotty
źródło
2

Oprócz wszystkich powyższych, myślę, że w grę wchodzi kilka innych czynników.

Jednym z nich jest to, że podczas kopiowania pliku należy go odczytać i zapisać; Hybernation wymaga tylko zapisu pliku. Z definicji jest już w pamięci!

Ściśle związane z tym, podczas odczytywania pliku i zapisywania go w tym samym czasie, w celu zaoszczędzenia pamięci, proces polega na: odczytaniu fragmentu, napisaniu fragmentu, aktualizacji katalogu (aby pokazać nowy rozmiar); przeczytaj fragment, napisz fragment, zaktualizuj katalog.

Za każdym razem, gdy przenosisz się z jednej części dysku do drugiej (np. Odczytaj plik a, aby zapisać plik b, napisz plik b, aby zapisać katalog i napisz katalog, aby odczytać następny fragment), dysk musi szukać - przesuń głowice, pozwól głowom osiąść, poczekaj, aż nadejdzie odpowiednia część dysku. Jest to jedna z zalet dysku półprzewodnikowego - wyszukiwanie nie zajmuje w ogóle czasu. Podczas hibernacji dane są zapisywane od końca do końca. Plik hibernacji (wymiany) jest wstępnie przydzielony, więc katalog nie musi być aktualizowany (nie zmieniasz rozmiaru pliku hibernacji, tylko zawartość).

I na koniec, twój komputer zawiesił wszystkie inne zadania - to JEDYNA rzecz, którą robi (wątpię, żeby to miało duże znaczenie, ale na pewno to zrobi!). Nawet rzeczy takie jak zarządzanie pamięcią i przełączanie zadań są zawieszone.

AMADANON Inc.
źródło
To na pewno zrobi ogromną różnicę!
Wyścigi lekkości na orbicie
@LightnessRacesinOrbit: rywalizacja z procesorem praktycznie nie robi żadnej różnicy. Brak rywalizacji o wejścia / wyjścia to wielka sprawa, ale ta odpowiedź już stwierdziła, że ​​szukanie zabija wydajność, a szukanie, a nie brak ogólnej przepustowości, jest głównym problemem w rywalizacji o wejścia / wyjścia.
Ben Voigt,
@BenVoigt: Tak, zgadzam się. A gdy masz 40 procesów, które wszystkie próbują robić rzeczy na dysku, znacznie zwiększy to wyszukiwanie dysku. (tl; dr Nie mówiłem o rywalizacji z procesorem)
Lightness Races in Orbit
@LightnessRacesinOrbit: Wydaje się to ... niezwykłe nawet podczas normalnej pracy (wszystko oprócz wchodzenia i wychodzenia ze stanu hibernacji). Wiem, że kiedy łapię zadanie w tle uderzające w dysk, odinstalowuję przyssawkę i zastępuję ją czymś, co uzyskuje dostęp do dysku tylko wtedy, gdy o to poproszę.
Ben Voigt,
@BenVoigt: Wydaje się to mało prawdopodobne. Rejestrowanie demona jest najbardziej oczywistym kontrprzykładem, po którym następują takie aktualizacje pliku drift ntpd. Nie twierdzę, że którykolwiek z tych przykładów ma tutaj duży wpływ, ale nie sądzę, że rozsądne jest oczekiwanie, że żadne zadania w tle nie dotkną dysku autonomicznie.
Wyścigi lekkości na orbicie
0

Wynika to prawdopodobnie z tego, że pamięć RAM ma znacznie szybsze prędkości wejścia / wyjścia niż dysk twardy, więc pamięć RAM może wysyłać zawartość tak szybko, jak dysk twardy może odczytać.

Podczas kopiowania plików ograniczają Cię także różne czynniki - prędkość dysku, jeśli będzie musiał wczytywać i wyjmować ten sam dysk, zajmie to więcej czasu, ograniczona prędkość połączenia (jeśli na dysku zewnętrznym), sprawdzanie go nie zastępuje niczego itp

Wilf
źródło
9
ale system operacyjny musi zapisać 4 GB pamięci RAM na dysku zarządzanym przez wąskie gardło we / wy
koder
Zakładając również korzystne parametry, oznacza to, że podczas hibernacji prędkość zapisu na moim dysku wzrasta z 40 MB / s do ~ 260 MB / s. Czy to może być poprawne?
koder
1
Prawdopodobnie - nie powinno być zbyt wiele wąskiego gardła we / wy, ponieważ musi on tylko zapisywać dane (prawdopodobnie jest coś na swoim miejscu, aby wiedzieć, że nie nadpisze rzeczy i gdzie umieścić dane, aby nie trzeba czytać dysk za dużo). Na moim (podwójnie uruchamianym) laptopie mogę używać dd if=/dev/zero of=/tmp/output.img bs=8k count=256ki pobierać 1862606848 bytes (1.9 GB) copied, 1.81605 s, 1.0 GB/s, więc wydaje się to możliwe (dodam, że i tak kopiowanie plików w systemie Windows wydaje się niepotrzebnie długo).
Wilf,
Możesz także uzyskać znacznie szybszy transfer podczas kopiowania plików przez lokalny internet. Może też nie być konieczne kopiowanie wszystkich danych z pamięci RAM - niektóre dane w pamięci RAM mogą być po prostu buforowane i nie będą potrzebne do przywracania systemu po wybudzeniu ze stanu hibernacji.
Wilf,
Właśnie wypróbowałem test porównawczy dd w moim systemie. Nigdy nie poszedł więcej niż 52 MB / s: / (stary komputer) Jednak uważam, że „prawdopodobnie coś jest na miejscu, więc wie, że nie zastąpi rzeczy i gdzie umieścić dane, aby nie musiał czytać dysku za dużo ” To klucz do dużej prędkości.
koder