Як Windows може так швидко скинути всю оперативну пам’ять у файл сплячки?


64

Я переглядав статтю, яка пояснювала процедуру сплячки в Microsoft Windows. Основні моменти, з яких я виходжу з цього, - це

  1. Windows скидає всю hiberfil.sysфайл оперативної пам’яті (можливо обробивши її) у файл.
  2. Під час завантаження файл сплячого режиму зчитується, а вміст завантажується в оперативну пам'ять.

Моє запитання, коли я зазвичай копіюю файл розміром, скажімо, 1 Гб, на це потрібно близько 2 хвилин .

Однак, коли Windows записує файл сплячки (під час процедури сплячки), весь процес займає, можливо, 10-15 секунд. Чому існує така різниця в швидкості запису?

Мій об'єм оперативної пам’яті - 4 Гб. (Я не говорю про технології швидкого завантаження.)

Орієнтири:

  1. Копіювання файлу 1 Гб з диска 1 на диск 2 (зовнішній): 2,3 хвилини.
  2. Гібернація системи: 15 секунд.

3
Я не знаю відповіді, але я ставлю на облік, якби ви перевірили книгу Windows Internals "Глава 13: Запуск та вимкнення", це сказало б вам (Якби у мене була книга, я би перевірив).
Скотт Чемберлен

2
Це гарне запитання. Коли сплячка була вперше введена в 1998 році, вона була не так вже й швидкою.
Гейб

22
@coder: у системі NT переконайтеся, що у hyberfil.sys виділено повний простір і весь файл не фрагментований. У такому стані під час роботи немає жорстких стрибків на жорсткому диску. Таким чином, ви отримаєте ефективні швидкості, наприклад, 150Mo / s. Ви можете повторно перевірити те, що я сказав fsutil.
користувач2284570

3
Зовнішній диск теж повільніше, ніж внутрішній.
Гаррі Джонстон

2
@EricLippert - це, звичайно, не зберігає всю оперативну пам’ять, але це все ще не пояснює це. У мене регулярно є кілька гігабайт активної оперативної пам’яті, яку потрібно зберігати (VS2013 або Eclipse + ще кілька речей займають багато оперативної пам’яті), і вони зберігаються зі швидкістю, яка мені здається більшою, ніж навіть теоретична швидкість запису мого не-SSD привід.
Давор

Відповіді:


45

Це, мабуть, триразова відповідь.

Одне, що може грати тут - це нове гібридне вимкнення в Windows, яке ефективно закриває ваші програми, вимикає вас з системи, а потім переходить у сплячку до ядра операційної системи. Вже збереження цих даних означатиме, що не потрібно потенційно «перезимувати».

Друга річ полягала б у тому, що у сплячому режимі не потрібно було б зберігати сторінки пам'яті, які або підключені до файлу swap, або не використовуються (це було б однією з причин агресивно заповнювати файл swap та зберігати дані також у пам'яті) .

Третім було б, що дані файлу сплячки також стискаються . Поєднайте це з моїм другим моментом, і якщо у вас є лише невеликий набір даних для експорту, який містить дуже стисливі дані (виконувані файли, як правило, добре стискаються), то кількість даних для виходу у файл сплячки може бути значно меншим, ніж робочий набір даних. Зауважте, що, як зазначено в коментарях, кеші файлів та інші непотрібні дані буфера можуть бути легко викинуті без поганого ефекту, щоб зменшити кількість даних, що викидаються у файл сплячки.

Крім того, поточні жорсткі диски досить швидкі. З диска, який має тривалу запис у порядку 100 Мб / с, ви зможете виписати (нестиснений) 4 Гб оперативної пам’яті за одну хвилину. Оскільки сплячий режим можна зробити як останнє після призупинення всіх процесів користувача та перед тим, як призупинити ЦП, ОС зазвичай матиме повну швидкість запису диска. Це одне, у чому простого еталону не буде, і копіювання з диска на диск потенційно буде повільніше, ніж просто записувати оперативну пам'ять на диск.

Поєднайте ці речі та обсяг даних, які слід записати у файл сплячки, може бути зовсім невеликим, потенційно порядку 1 Гб, і, ймовірно, записується до одного великого безперервного блоку за 10 секунд.


37
Або, щоб зробити це більш зрозумілим: ваша ОЗУ, ймовірно, не заповнена. Буфери змиваються і кеш викидається при сплячому режимі. На диск має бути записана лише пам'ять, яка фактично використовується додатками . Гібридне вимкнення зменшує обсяг пам’яті, що використовується, виходячи з користувача.
Даніель Б

2
Сторінки, які не є брудними, - це більш загальне твердження про "підключення до файлу swap", воно включає в себе виконувані файли. (Оскільки виконувані файли дещо фрагментовані на диску, це може сповільнити пробудження.) Крім того, чисті файлові буфери, ймовірно, можуть бути просто скинуті, навіть якщо вони не є частиною файлу, відображеного на пам'ять.
Пол А. Клейтон

3
@ user2284570 з документа, який я пов’язував у цій відповіді "Windows підтримує сплячку, копіюючи вміст пам'яті на диск. Система стискає вміст пам'яті перед збереженням їх на диску, що зменшує необхідний простір на диску менше, ніж загальний обсяг фізичної пам'яті за системою ".
Мокубай

4
@ user2284570: Це тому, що найгірший сценарій - стиснення 1: 1. Windows має переконатися, що в hyberfil.sys достатньо (зарезервованого) місця для будь-якої можливої ​​конфігурації пам'яті - навіть якщо для конкретної сплячки їй потрібна лише десята частина розміру оперативної пам’яті. Додайте до цього, що гідна частина оперативної пам’яті - це файли, завантажені в пам’ять (виконувані файли, ресурси ...), але все-таки відображені з жорсткого диска, і ви дійсно можете зберегти багато запису. Запропонуйте програмі генерувати 4 ГБ крипто-випадкових даних в оперативній пам’яті, і сплячий режим займає значно більше часу - і навіть тоді деякі з них могли бути замінені.
Луань

3
@ user2284570: Файл настільки великий, щоб забезпечити місце на диску для зберігання всієї пам'яті. Не весь цей простір насправді використовується в сплячому режимі. Іноді у файлі буде (скажімо) 7% стислий вміст пам'яті, 93% непотрібне.
psmears

31

По-перше, обсяг оперативної пам’яті, який потрібно зберегти, напрочуд невеликий. Насправді потрібно промити лише набір зіставлених брудних сторінок ("ледачий запис"), а також потрібно записати всі приватні сторінки, записані та переміщені виконуваним кодом.

  • Сегменти .text виконуваних файлів завжди підкріплюються картографічним відображенням. Це також стосується принаймні деяких DLL (але не всіх, залежить від того, чи потрібно їх переселяти).
  • Пам'ять, яка підтримується аналогічно зі зіставленням файлів, може бути викинута (припускається, що вона не є КВ або RW та забруднена).
  • Ліниве списання все ж доведеться мати, але крім цього, кеші можна відкинути.
  • Пам'ять, яка була виділена, але не записана (зазвичай більша частина даних програми!), Підтримується нульовою сторінкою і може бути відкинута.
  • Більша частина сторінок пам'яті, які знаходяться в режимі "очікування" (фактичний робочий набір резидента в процесі роботи в Windows на диво невеликий, лише 16 Мб) буде скопійовано у файл сторінки у фоновому режимі в якийсь момент і може бути відкинуто. .
  • Регіони пам'яті, відображені на певних пристроях, таких як відеокарта, можуть (можливо) не потребувати збереження. Користувачі іноді дивуються, що вони підключають 8GiB або 16GiB до комп’ютера, а 1GiB або 2GiB просто "пішли" без видимих ​​причин. Основні графічні інтерфейси API вимагають можливості додатків із вмістом буфера стає недійсним "за певних умов" (не вказуючи точно, що це означає). Таким чином, нерозумно очікувати, що пам'ять, яку закріплює графічний драйвер, теж просто відкидається. Зрештою, екран затьмариться.

По-друге, на відміну від копіювання файлу, скидання набору сторінок оперативної пам’яті, на яких потрібно зберегти диск, є єдиним послідовним, суміжним записом з точки зору накопичувача. API Win32 навіть розкриває функцію на рівні користувача для цієї самої операції. Збір записів безпосередньо підтримується апаратним забезпеченням і працює так само швидко, як диск фізично здатний приймати дані (контролер буде безпосередньо перетягувати дані через DMA).
Існує ряд передумов для цього (наприклад, вирівнювання, розмір блоку, закріплення), і це не добре грає з кешуванням, і немає такого поняття, як "ледачий відкат" (що дуже бажана оптимізація при нормальній роботі ).
Ось чому не кожен пишепрацює так постійно. Однак, коли система зберігає файл сплячки, всі передумови автоматично виконуються (всі дані вирівнюються за сторінками, розміром сторінки та закріплюються), а кешування просто стає неактуальним, оскільки комп'ютер буде вимкнено за мить.

По-третє, ведення одночасного запису дуже сприятливо як для прядильних дисків, так і для твердотільних дисків.

Файл swap і файл сплячки зазвичай є одними з найбільш ранніх файлів, створених і зарезервованих на диску. Зазвичай вони мають один, максимум два фрагменти. Таким чином, якщо сектори не пошкоджені і диск не повинен перерозподілити фізичні сектори, логічне послідовне записування перекладається на фізичне послідовне записування на обертовому диску.

Жодні операції читання-зміни-запису на диску не потрібні, коли записується величезна кількість послідовних, суміжних даних. Ця проблема менш виражена на спінінг-жорстких дисках, які можуть записувати поодинокі сектори, які є досить маленькими (за умови, що ви не пишете одиничних байтів, що кешування зазвичай перешкоджає, пристрою не потрібно вибирати оригінальний вміст і записувати назад модифіковану версію.) .
Це, однак, є дуже помітним на SSD, коли кожне записування означає, що, наприклад, блок 512 Кб (це звичайне число, але воно може бути більшим) має бути прочитаний і змінений контролером, і записаний назад до іншого блок. Хоча в принципі можна писати в (але не перезаписувати)) менші одиниці на флеш-дисках, ви можете коли-небудь стирати величезні блоки, це як працює апаратне забезпечення. Це причина, чому SSD дешевшає на величезних послідовних записах.


Навіть якщо DLL переміщена, єдине, що потрібно, щоб повернути її, - це перенесена адреса. Переселення є детермінованим процесом і може повторюватися.
MSalters

"Зберіть писати"? Ви маєте на увазі "Швидше пишіть"?
Пітер Мортенсен

3
@PeterMortensen: Ні, я дійсно маю на увазі збирання запису (на відміну від розкидання читання). Це означає запис у один файл, збираючи дані з кількох місць. Ви надаєте масив структур, кожна з яких містить стартову адресу та довжину (з чіткими вимогами до вирівнювання). Операційна система передає їх контролеру, а апаратура робить все інше.
Деймон

1
@MSalters: Але переїзд створює приватну копію сторінки, і тоді надзвичайно важко визначити, чи були внесені інші зміни в приватну копію. Контрастуйте із відображеннями, які не потребували налаштування, і використовуйте копіювати при записі. Якщо будуть внесені інші модифікації, з'явиться приватна копія. Якщо ні, сторінка все одно буде налаштована для CoW.
Бен Войгт

1
@MSalters Це може бути детермінований процес, але це не означає, що код сплячки працює на тому ж рівні програмного стеку, що і лінкер. Якщо сплячка знаходиться на рівні ядра, а посилання - на користувальницький рівень, тоді сплячка не може робити жодних припущень щодо того, що робить лінкер.
kasperd

10

Це не скидає всю оперативну пам'ять у сплячий час.

Він вже матиме велику частину оперативної пам’яті, вже дублюється на диску. Це не лише дозволяє швидко перенести сплячку, але також дозволяє швидко отримати доступ до пам'яті для нових програм (щоб вони могли швидко запускатися).

Тому потрібно записати лише невелику частку 4 Гб, і це можна зробити за 10-15 секунд.

Від мікрософт :

Коли оперативної пам’яті не вистачає (наприклад, відданих байтів більше встановленої оперативної пам’яті), операційна система намагатиметься зберегти певну частину встановленої оперативної пам’яті для негайного використання, копіюючи сторінки віртуальної пам’яті, які не активно використовуються, у файл файлу сторінки . Тому цей лічильник не досягне нуля і не обов'язково є хорошим показником того, чи не вистачає вашій системі оперативної пам’яті.


2

На додаток до всього вищесказаного, я думаю, що є ще кілька факторів.

Одне полягає в тому, що при копіюванні файлу файл повинен бути прочитаний і записаний; Гібернація вимагає, щоб файл був записаний. Це, за визначенням, вже в пам’яті!

Тісно пов’язане з цим, коли читаєш файл і одночасно пишеш його, щоб зберегти пам’ять, процес такий: прочитати фрагмент, написати шматок, оновити каталог (показати новий розмір); прочитати шматок, написати шматок, оновити каталог.

Кожен раз, коли ви переходите з однієї частини диска в іншу (наприклад, читайте файл a, щоб записати файл b, записувати файл b, щоб написати каталог, і записуйте каталог, щоб прочитати наступний фрагмент), диск повинен шукати - переміщуйте головки, дозвольте головам осісти, зачекайте, поки потрібна частина диска підійде. Це одна з переваг твердотільного диска - пошук не потребує зовсім часу. При сплячому режимі дані записуються в кінці. Файл гібернації (swap) заздалегідь призначений, тому каталог не потрібно оновлювати (ви не змінюєте розмір файла сплячки, а лише вміст).

І нарешті, ваш комп’ютер призупинив усі інші завдання - це ТІЛЬКІ речі, які він робить (я сумніваюся, це матиме велике значення, але це обов'язково зробить деякі!). Навіть такі речі, як управління пам'яттю та переключення завдань, призупинено.


Це неодмінно змінить велику кількість !
Гонки легкості на Орбіті

@LightnessRacesinOrbit: суперечки процесора взагалі не матимуть ніякої різниці. Відсутність суперечок вводу-виводу є великою справою, але ця відповідь уже зазначала, що пошук спроби вбивати продуктивність, а пошук, а не відсутність загальної пропускної здатності, є головною проблемою в суперечці вводу-виводу.
Бен Войгт

@BenVoigt: Так, я згоден. І якщо у вас 40 процесів, які всі намагаються робити речі на диску, це істотно збільшить пошук диска. (tl; доктор, я не говорив про суперечності процесора)
гонки легкості на орбіті

@LightnessRacesinOrbit: Це здається… незвичним навіть під час звичайної роботи (все, крім входу та сходу зі сплячки). Я знаю, що коли я вловлюю фонове завдання, що потрапляє на диск, я видаляю присоску і замінюю її чимось, що отримує доступ до диска лише тоді, коли я щось запитую.
Бен Войгт

@BenVoigt: Це здається малоймовірним. Ведення журналу Daemon є найбільш очевидним контрприкладом, за яким слідують такі речі, як оновлення файлу дрейфу ntpd. Я не стверджую, що жоден із цих прикладів тут не має великого ефекту, але я не думаю, що розумно очікувати, що фонові завдання не торкаються диска автономно.
Гонки легкості на Орбіті

0

Це, мабуть, тому, що оперативна пам'ять має набагато більші швидкості введення / виведення, ніж жорсткий диск, тому оперативна пам'ять може виводити в неї речі так само швидко, як і на жорсткому диску.

Коли ви копіюєте файли, ви також обмежені різними факторами - швидкістю диска, якщо він повинен читати і виходити на один і той же диск, це займе більше часу, обмежена швидкість з'єднання (якщо до зовнішнього диска), перевірка цього не перезаписує нічого тощо


9
але все-таки ОС потрібно записати дані оперативної пам’яті 4 Гб на диск, яким керує вузьке місце вводу-виводу
кодер

Зважаючи на сприятливі параметри, це означає, що під час сну швидкість запису мого диска падає від 40 МБ / с до ~ 260 МБ / с. Чи може це бути правильно?
кодер

1
Ймовірно - вузького місця вводу-виводу не повинно бути занадто багато, оскільки потрібно лише записати дані (можливо, щось є на місці, щоб він знав, що він не буде перезаписати речі, і куди потрібно розмістити дані, щоб вони не сталися потрібно занадто багато читати диск). На моєму (linux dual boot) ноутбуці я можу використовувати dd if=/dev/zero of=/tmp/output.img bs=8k count=256kта отримувати 1862606848 bytes (1.9 GB) copied, 1.81605 s, 1.0 GB/s, тому, здається, це можливо (додам, що копіювання файлів у Windows все одно займе довгий час).
Вільф

Ви також можете отримати набагато швидшу передачу при копіюванні файлів через локальний Інтернет. Крім того, можливо, не потрібно буде копіювати всі речі в оперативній пам’яті - деякі дані в оперативній пам'яті можуть бути просто кешовані і не потрібні для відновлення системи під час пробудження після сплячки.
Вільф

Я щойно спробував орієнтир dd у своїй системі. Він ніколи не перевищував 52 Мб / с: / (стара машина) Однак я вважаю, що "напевно є щось на місці, тому він знає, що він не буде перезаписувати речі, і куди розміщувати дані, щоб не потрібно читати диск занадто багато " є ключем для швидкої швидкості.
кодер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.