Перевод статьи Рэймонда Чена, более 25 лет участвовавшего в разработке ОС Windows, автора блога The Old New Thing, начатого им в 2003 году.

С выходом Windows 95 появилось большое количество программных продуктов, предназначенных специально для этой ОС. Много внимания в какой-то момент привлекла одна из таких программ – SoftRAM 95. На коробке значилось, что программа может «удвоить вашу память».

Оказалось, что не может.

Я встречал несколько статей, описывавших, что эта программа делала (а главное – не делала), но почти нигде авторы не углублялись в код и не описывали, как именно она работала. Поэтому я решил написать такую статью.

В конце 1995 года меня попросили разобраться с этим продуктом – он приводил к падению Windows 95, из-за него в поддержку поступало множество звонков, не говоря уже о том, что он делал ОС антирекламу. Была вероятность того, что программа каким-то образом взаимодействовала с неизвестной ошибкой в Windows 95, и нам нужно было найти её и пропатчить.

В итоге мне пришлось дизассемблировать их собственный драйвер подкачки страниц. В набор средств разработки драйверов (DDK) Windows 3.0 и 3.1 входил исходный код драйвера подкачки, и их драйвер был, очевидно, основан на коде, поставлявшемся в одном из старых DDK.

Они размещали кусок невыгружаемой памяти [non-paged memory] при старте системы и использовали его в качестве пула сжатия. При выгрузке участков памяти драйвер сжимал память и добавлял её к пулу. Каждый блок буфера сжатия начинался с байта, обозначавшего алгоритм сжатия, за которым следовали сжатые данные.

Когда система запрашивала определённую страницу памяти, драйвер проверял, нет ли её сжатой копии в пуле. Если она там была, он разжимал её и возвращал. В ином случае он считывал память с диска, только довольно странным методом.

Для ясности я нарисовал картинки. Будем ранжировать страницы системы по вероятности того, что к ним обратятся. Левее будут горячие страницы, к которым будут обращаться вероятнее всего. Правее – холодные, к которым обратятся с меньшей вероятностью. Система без изменений выглядит так:



В данном примере воображаемой системы в памяти имеется 16 самых горячих страниц, а остальные хранятся на диске. Размер секции «в памяти» равен объёму установленного ОЗУ. Размер секции «на диске» может расти до максимального размера файла подкачки.

При размещении новой страницы она вставляется слева как наиболее горячая. Поскольку размер секции «в памяти» ограничен, самые холодные из горячих страниц выталкиваются на диск. В среднем почти все страницы в системе холодные, поэтому масштаб приведённой выше диаграммы не соблюдён. Размер секции «на диске» гораздо больше, чем «в памяти», однако поскольку всё самое интересное происходит в секции «в памяти», я нарисовал её побольше.

Идея состоит в том, чтобы сжать часть хранящихся в памяти страниц:



Берём половину памяти системы и сжимаем. На диаграмме размер сжатых страниц меньше, чем несжатых. Это подчёркивает, что общее количество памяти не менялось. Поменялся лишь метод использования этой памяти.

Могу перерисовать диаграмму так, чтобы размеры всех страниц сохранились. С точки зрения приложений и менеджера памяти система теперь выглядит так:



С точки зрения остальной системы всё выглядит так, будто у вас появилось больше памяти.

К сжатой памяти нельзя обратиться сразу же, по необходимости, как это делается с обычной памятью. Когда приложение запрашивает доступ к памяти, которая оказывается сжатой, сжатые данные распаковываются в обычную страницу памяти, а страница с низшим рангом становится сжатой. На все эти сжатия и распаковки уходит время, но это всё равно получается быстрее, чем работать с диском.

Если я правильно помню, сжатые данные обрабатывались просто – через кольцевой буфер. После сжатия новая страница добавлялась к буферу, а при необходимости освободить место выбиралась страница в голове буфера. Таким способом очень просто следить за происходящим, однако эффективность при этом страдает. Когда страницу переносили из буфера со сжатием в память, а потом вносили обратно в буфер, память из-под старых сжатых данных просто тратила место. Теоретически можно было бы сразу же использовать освобождавшееся место, однако это усложнило бы алгоритмы работы с памятью из-за фрагментации. Тогда ещё все драйверы писали на ассемблере. Простота схемы была важна, поскольку реализовывать её приходилось при помощи низкоуровневых инструкций.

Расчёт шёл на то, что даже если вы убирали из памяти кучку быстрых страниц, вы меняли их на большее количество страниц средней скорости, что уменьшало количество обращений к медленным страницам. В примере выше мы предполагаем сжатие в два раза, поэтому мы убираем 8 быстрых страниц и превращаем их в 16 страниц со средней скоростью доступа.

До После
Обычных страниц 16 8
Сжатых страниц 0 16
Страниц на диске N N-8


Получится ли выиграть время – зависит от закономерностей доступа к памяти у конкретных приложений. Если у вашего приложения 6 очень горячих страниц и ещё 14 тёплых, то прирост к скорости будет – очень горячие страницы могут оставаться в нормальной памяти, а 14 тёплых будут меняться местами, занимая два последних слота среди нормальных страниц. С другой стороны, если у приложения 10 очень горячих страниц и 10 тёплых, получится проигрыш, поскольку нормальных страниц в памяти для удержания всех горячих страниц не хватает, и вы постоянно будете сжимать и разжимать память, и всё это лишнее потраченное время может нивелировать время, выигранное на устранении обращений к диску, к тем страницам, что не помещались в память раньше.

Видно, что вся схема зависит от качества движка сжатия. Необходимо втискивать в сжатые страницы побольше данных, чтобы восполнить потерю доступа к нормальным страницам большим количеством сжатых страниц.

Я нашёл этот алгоритм сжатия. Он вызывался для того, чтобы извлечь память из буфера ввода/вывода и сжать её, поместив в буфер сжатия. Его напарник, алгоритм распаковки, использовался при запросах к страницам, распаковывал их из буфера сжатия и помещал в буфер ввода/вывода.

Разработчики реализовали только один алгоритм сжатия. И это был memcpy.

Иначе говоря, их хвалёный запатентованный алгоритм сжатия состоял в том, чтобы копировать данные без сжатия.

Архитектура для сжатия была реализована, а вставленная в качестве заглушки функция ничего не сжимала. Видимо, они решили, что в будущем вставят туда крутую функцию сжатия, а пока только протестируют всю схему. Однако времени на это у них не осталось, и они выпустили продукт с заглушкой.

В результате получилось что-то виртуального диска в памяти, где хранится файл подкачки. Некоторые страницы просто изымались из списка «быстрых» и превращались в страницы в списке «средней скорости».

Пока что получалось что-то вроде плацебо с небольшим падением эффективности. Но почему всё это в итоге падало? Наткнулась ли их программа на ошибку в менеджере памяти Windows 95?

Добавив код для реализации буфера сжатия, они не использовали ни критические секции, ни любые другие примитивы синхронизации для защиты структур данных. Если два потока начинали подкачку одновременно, драйвер портил структуры данных. В следующий раз, когда драйвер распаковывал страницу, он ошибался, и выдавал не ту страницу, которая была нужна.

Они, по сути, случайно симулировали сломанный жёсткий диск.

Также это объясняло, почему падения происходили, когда в системе активно шла подкачка страниц. В таких условиях вероятность наложения двух запросов к памяти повышалась.

Я упоминал, что их драйвер был основан на том, что шёл в DDK. Они даже не поменяли имя в блоке описания драйвера. Поэтому когда он падал, выдавалась ошибка PAGEFILE. А поскольку это название драйвера подкачки по умолчанию, всё выглядело так, будто упал штатный драйвер Windows, хотя на самом деле падала их замена с таким же названием.

Я, кстати, не единственный, кто разбирался в работе SoftRAM. Некий товарищ по имени Марк Руссинович тоже разобрал эту программу и пришёл к тем же выводам. Интересно, что с ним стало. Человек-то вроде умный.

Мой коллега отметил, что SoftRAM стала продолжением похожего продукта, разработанного для Windows 3.1. В этой ОС использовалось два способа увеличения количества программ, которые можно запускать одновременно. Во-первых, увеличивался размер файла подкачки – но это, кстати, можно было сделать и вручную. Во-вторых, там использовались определённые трюки, позволявшие не хранить определённые компоненты в обычной памяти. Эти трюки были известны инструментам для оптимизации системы. У Microsoft можно было даже бесплатно скачать программу, занимавшуюся тем же самым – её как раз написал этот мой коллега. В Windows 95 использовался динамический файл подкачки, и он также решал проблему с обычной памятью, из-за чего программе, портированной с Windows 3.1 на Windows 95, заниматься было уже нечем.

Говорят, кстати, что у той компании было два разработчика, один из которых разрабатывал драйвер, а другой – пользовательский интерфейс. Видимо, им не хватило третьего специалиста, который реализовал бы алгоритм сжатия.

Мой тогдашний начальник, кстати, как-то ездил на торговую выставку, на которой, в том числе, присутствовал и производитель программы SoftRAM. По окончанию выставки он обменялся футболками с представителем той компании, а потом отдал футболку мне.

Как же эта программа заработала стикер «Разработано для Windows 95?» Просто: она была разработана для Windows 95. Для этого нужно было просто следовать определённым правилам – типа использования стандартного диалога для открытия файла или установки в директорию Program Files. Всем требованиям программа соответствовала, поэтому ей выдали такую наклейку.

Некоторые специалисты говорят, что она не выполнила правило, по которому реальная работа программы должна в значительной степени соответствовать её рекламному описанию, однако никто не требовал, чтобы каждое заявление было проверено независимыми специалистами путём глубокого реверс-инжиниринга.

Если бы такой стандарт существовал, на утверждение каждого продукта уходили бы годы. Чтобы проверить программу «выучи немецкий за 30 дней», нужно было бы проверить, что в ней используется правильный словарь и правильная грамматика, а потом посадить бы кого-нибудь за неё на 30 дней, и посмотреть, выучил ли он немецкий. Правило предназначалось для того, чтобы отсекать программы, не соответствовавшие минимальным системным требованиям, или программы, которые заявлялись, как текстовый процессор, а на деле играли бы в крестики-нолики.

Комментарии (32)


  1. entze
    16.11.2021 16:45
    +3

     Интересно, что с ним стало. Человек-то вроде умный.

    У него всё в ажуре.

    Win вроде сам поджимает память, правда не любую. Интересно про это почитать.


    1. Vladekk
      16.11.2021 17:14
      +14

      Про Русиновича это шутка, я на 100% уверен, что Чен с ним бухал сто раз.


      1. entze
        16.11.2021 17:51
        +9

        Это понятно, я добавил уровень. Марк - CTO of Microsoft Azure


    1. a-tk
      17.11.2021 22:17

      Это появилось несколько позже чем Win95


  1. SShtole
    16.11.2021 17:24
    -1

    В итоге мне пришлось дизассемблировать их собственный драйвер подкачки страниц.

    Интересно, а лицензия на SoftRAM не включала в себя пункт о запрете дизассемблирования? Вроде бы, типичный пункт был в те времена. Причём, у Чена половина постов про то, как он раскурочил чужой софт, иногда от недоброжелательно настроенных компаний (конечно же, в целях обеспечения соместимости).


  1. DrMefistO
    16.11.2021 17:27
    +21

    Без сомнений, вишенка на торте у данной статьи это "некий Руссинович".


  1. YMA
    16.11.2021 17:45
    +1

    Во времена Win95 было много интересного в плане системных утилит, сейчас как-то скучнее.

    Очень нравилась программа VRAMdir - которая позволяла указать любой каталог на диске, и все записи и чтения в него направлять в память. Замапил туда временный каталог и кэш браузера - и получай хороший прирост скорости.


    1. aborouhin
      16.11.2021 20:24
      +2

      То-то любителям этих "утилит", а я сам к таким в те годы относился, приходилось с завидной регулярностью систему переустанавливать :) Уж лучше скучнее, право слово.

      Хотя аналог VRAMdir, вроде, есть и под Win 10. И не один.


      1. gban
        17.11.2021 02:45
        +1

        >То-то любителям этих "утилит", а я сам к таким в те годы относился, приходилось с завидной регулярностью систему переустанавливать :)

        так мы изучали реестр win95... :)


      1. YMA
        17.11.2021 11:06

        Не, RAMdrive всяких под все ОС хватает. А тут была фишка именно с маппингом любого каталога на уже существующем диске, без всяких сим- и хардлинков и прочих извращений. И память выделялась динамически - сколько есть данных, столько и задействовалось.


      1. PKav
        17.11.2021 14:49

        Win9x в принципе приходилось переустанавливать регулярно, т.к. она могла перестать загружаться или начать выдавать кучу системных ошибок в любой момент. И даже пиратов тут не обвинить, т.к. кроме проверки текстового ключа при установке никакой защиты не было.


        1. aborouhin
          17.11.2021 16:19
          +1

          Вот поэтому, когда я году в 1998 первый раз поставил Windows NT 4, я так поразился открывшемуся мне невиданному уровню стабильности, что обратно на 95/98 уже и не возвращался никогда :)


        1. drWhy
          17.11.2021 18:15

          КМК использование FAT усугубляло ситуацию, с каждой такой перезагрузкой накапливая ошибки, которые бравый чекдиск мог залечить вплоть до потери папки Windows а то и всего раздела. На NTFS Windows 95/98 трудилась заметно надёжнее.


          1. YMA
            17.11.2021 18:31

            Win95 - на NTFS? Про драйверы для работы с NTFS (зело глючные и нестабильные) слышал, но работать с нее - ни разу...


            1. drWhy
              17.11.2021 18:49

              Моя ошибка. Почему-то вспомнилась утилита convert.exe в связи с Windows 95.


          1. PKav
            17.11.2021 18:37
            +2

            Windows 95 и 98 не поддерживали NTFS. Она потому и называется NTFS, что была создана для NT. Но дело скорее не в файловой системе, а в сырости и кривизне программного кода в целом. Самая первая версия Windows XP, без установленных Service Pack разваливалась не менее регулярно, вплоть до того, что пользователям пиратской версии можно было даже не взламывать механизм активации, т.к. система часто переставала работать до того, как истекут 30 дней триала.


            1. drWhy
              17.11.2021 18:46

              Конечно же, перепутал с XP.
              Всё же от Windows 95/98 остались положительные впечатления.


        1. TigerClaw
          17.11.2021 19:55

          Кстати вот постоянно слышу, что приходилось переустанавливать регулярно. Но вот я не переставлял регулярно что я делал не так? По сути все установки это разные версии Windows 9x благо было их много. Плюс пиратская версия X-com 3, которая у меня была крашила файловую систему насмерть. Плюс апгрейд винчестера и самого компа. По сегодняшним меркам покажется, что установок много. Но это все же не регулярная переустановка.


          1. PKav
            18.11.2021 00:00

            В принципе, если все установить, настроить и ничего не трогать, то даже такая система могла жить долго. Но это, скорее, исключение, чем правило.


          1. axe_chita
            18.11.2021 21:13

            Вспомню баян: " В техподдержку Микрософт звонит женщина, и начинает благодарить Микрософт что Windows 95 такая надежная и быстрая система, ни разу у нее не зависала, или сбоила, что все-все замечательно, что вы все вери-вери бест!".
            Возникает неловкая пауза на пару минут и специалист тех поддержки тихо интересуется — «А вы пытались включать компьютер?»"


            1. TigerClaw
              18.11.2021 22:10

              Но если серьезно то ПК использовался конечно ни как сейчас 24/7. Но каждый день по 4-8 часов минимум. Но это было время когда ПК еще выключали, много игр игралось в досе. Виндовс кстати ставилась часто не с нуля, а поверх имеющейся. Но это все же нельзя сравнить с текущими обновлениями.
              Вообще мое личное мнение не зависимо от версий на излете своего существования с актуальным железом windows начинает работать так себе. Поэтому если вовремя уйти с 98se желательно пропустив Me, то многих проблем можно было избежать. Хотя сам еще какое то время использовал одновременно 98se и XP. Но первая использовалась для ряда игр и работы сканера. А последняя для интернета, актуальных игр и вдруг просмотра фильмов. Но со временем от 9x отказался вообще. Последний же раз две разные Windows использовались когда вышла Vista. Там тоже не сразу удалось на нее мигрировать из-за плохой поддержки старого железа в годе ее выхода.


              1. axe_chita
                19.11.2021 20:50

                Если серьезно, это был бородатый анекдот времен мастдая.
                У 9х линейки были определенные проблемы с аптаймом, ЕМНИП из-за того что была туева хуча костылей, скотча, хаков в самой архитектуре. Особо остро это проявлялось в 3D графике (зd studio, maya и так далее). И когда появилась альтернатива в виде NT4, то народ что называется ломанулся туда, где твой процесс многосуточного рендера видеоролика зd studio не рухнет из-за прихотей ОС.


                1. TigerClaw
                  19.11.2021 21:31

                  Вот как раз аптайм тогда у меня был небольшой. Впервые 24/7 я стал использовать комп во времена XP, безлимитного ночного диалапа. Сначало это было тяжело. Ибо вдруг несмотря на то, что современные ПК порой похожи на турбореактивных монстров они все же тише в простое.


      1. IGR2014
        17.11.2021 16:13

        del


      1. JamesonRU
        19.11.2021 00:08

        Я вот отказался от storemi, правда там дисковый кеш, но даже его время версия мне уронила системный раздел. Первая же работала по такому алгоритму что я до сих пор пот утираю как я по краю прошел без потерь


  1. Fragster
    16.11.2021 18:07
    +3

    Тем не менее идея рабочая: я получал более чем двукратный прирост эффективной памяти на "vds за 30 рублей" при использовании свопа на zram (доходило до более чем 850мб без свопа на реальный диск).


    1. quwy
      18.11.2021 02:01

      Так zram реально жмет данные.

      В винде, кстати, механизм динамического сжатия страниц тоже давно встроен.


  1. axe_chita
    17.11.2021 09:23
    +2

    Кстати, а в QEMM97 была утилита MagnaRAM, которая действительно сжимала данные помещаемые в виртуальную память. ЕМНИП то эффект от нее был.


  1. IGR2014
    17.11.2021 16:11

    Забавно что сейчас в Windows 10 встроен подобный-же механизм:
    https://www.howtogeek.com/319933/what-is-memory-compression-in-windows-10/


    1. Fragster
      17.11.2021 16:33

      Оно там совсем не такое агрессивное:

      и я вообще не видел,, чтобы на таком объеме оно показывало больше сотни мегабайт сжатой памяти. При этом в линуксе с zram все очень прозрачно и просто управляемо.


  1. ComodoHacker
    17.11.2021 16:53

    Они размещали кусок невыгружаемой памяти

    Все-таки allocated лучше переводить как "выделяли".


  1. bluetooth
    17.11.2021 17:34

    Некий товарищ по имени Марк Руссинович ... Интересно, что с ним стало. Человек-то вроде умный.

    Рассмешило :D