Пользователь
30,7
рейтинг
24 октября 2011 в 12:30

Разработка → Ускоряем загрузку карты в World of Tanks


Заметил я как-то, что на моём компьютере карты в WoT загружаются очень долго — больше минуты. Заходишь, бывает, в бой, а он уже секунд 30 идёт. А иногда вообще обнаруживаешь свой танк уже в виде горящих обломков. Компьютер мой, конечно, старенький и давно просит апгрейда, но вначале можно попытаться сделать что-то программным путём.

Итак, первое дело — определить причину тормозов. Список подозреваемых, в принципе, не очень большой:
  • CPU
  • RAM
  • HDD
  • Сеть
  • Криворукость разработчиков игры
  • Барабашка
Начнём оперативно-розыскные мероприятия с очной ставки. Берём прекрасную утилиту Process Monitor от Sysinternals, запускаем, добавляем в фильтры мониторинг процесса worldoftanks.exe и — поехали. Стартуем игру, начинаем бой, ждём загрузки карты и смотрим на результаты мониторинга.

Как видно из скриншота, загрузка CPU, памяти и сети далеки от максимальных. А вот график загрузки HDD весьма неровный, есть пики и провалы. Давайте посмотрим детальнее. Жмём «Tools->File summary...». Бинго! Тут мы видим целую кучу операций ввода\вывода (70 602 штуки, если быть точным).

Общий объем читаемых по ходу загрузки данных составляет примерно 450 МБ, время работы файловых операций — более 50 сек. Значит именно файловые операции занимают большую часть времени загрузки карты. Оно и немудрено — в WoT хорошо проработанные карты, модели танков, всякие там дома\деревья\камни. 450 МБ читаемых данных выглядит адекватной ценой за всё это. Но как же мы можем ускорить время загрузки? Ведь все эти данные игре всё-равно нужно прочитать. Есть старый проверенный способ ускорения файловых операций — RAM диск. Но вот в чём беда — в лоб применить его не выйдет. Игра занимает 11 ГБ, а на моей машине всего 4 ГБ ОЗУ. То есть даже создав RAM диск размером 11 ГБ и поместив на него всю игру, я не обману законы физики и операционную систему — диск может и создастся, но данные на нём будут свопится на всё тот же жесткий диск, от использования которого мы хотим уйти. Не вариант.

Что ж, копнём глубже — посмотрим, обращения к каким именно файлам занимает больше всего времени. Открываем вкладку «By folder» и видим следующую картину.

Большую часть ресурсов кушает обращение к файлам в папке %World_of_tanks%\res. Тут можно выделить следующие подпапки:
  • audio: 14.48 сек — папка занимает 200 МБ
  • content: 9.93 сек — папка занимает 844 МБ
  • spaces: 6.19 сек — папка занимает 419 МБ
  • vehicles: 8.60 сек — папка занимает 1.7 ГБ
Если бы мы могли поместить в память файлы из некоторых этих папок, то загрузка карты значительно бы ускорилась. Например поместив в ОЗУ файлы из папок audio и spaces, мы выиграем 21 секунду времени ценой 619 МБ ОЗУ — вполне неплохо. Но в лоб этого сделать не выйдет — как же игре объяснишь, что часть её ресурсов лежит тут, а часть — там? В этом месте я уже хотел удариться в жёсткий хардкор в духе Harkonnen'a:
  1. Загружаем нужные файлы в память
  2. С помощью какого-нибудь Microsoft Detours или ApiHijack вешаем хуки на функции CreateFile, ReadFile (и может что-то еще) в процессе Worldoftanks.exe.
  3. В хуках определяем, какой именно файл пытается читать WoT. Если один из наших — даём ему данные из памяти, если левый — перекидываем вызов на настоящие функции файлового ввода\вывода.

Но, к сожалению, не сложилось — мне в голову пришла идея, которая позволила сделать всё в разы проще и этим всё испортила :). Идея состояла в том, что, дескать, как бы классно в этом месте было бы быть пользователем *nix-систем, где есть прекрасная команда mount, позволяющая примонтировать что угодно куда угодно. В Windows такого нет… Или есть? На периферии сознания витали какие-то смутные воспоминания и я полез в голову и Гугл за информацией (когда уже ребята из Гугла в конце-концов сделают поиск в моей голове — совсем обленились что-то!). Итак, вот что мы имеем под Windows:

  • subst — делает ровно противоположное тому, что нам надо. Позволяет создать новый виртуальный диск, корнем которого будет являться заданная папка. А нам нужно наоборот — связать существующий диск с «виртуальной» папкой.
  • Cпособ, описанный в Microsoft KB 307889 — на первый взгляд делает то, что нам нужно. Позволяет для файловой системы NTFS создать связь между некоторой папкой и корнем диска. Прекрасная штука, но, к сожалению, не заработала с моим RAM-drive (даже когда я отформатировал его в NTFS).
  • Ну и наконец я решил поискать там, откуда подобный поиск следовало начинать — в списке утилит от Sysinternals. И, конечно же, там нашлось то, что мне было нужно. Утилитка Junction позволяет примонтировать к определенной папке любой путь в нашей файловой системе (есть еще одна похожая — linkd).
Таким образом, окончательный алгоритм выглядит так:
  1. Берём любой RAM-drive (например из вот-этого списка). Я взял вот этот.
  2. Думаем, сколько ОЗУ мы можем выделить под кеширование.
  3. Переписываем папки с ресурсами игры на RAM-drive (оригинальные папки переименовываем — они нам еще понадобятся).
  4. С помощью Junction монтируем папки на Ramdrive в папку ресурсов игры. Как-то так:
    «junction D:\Games\World_of_Tanks\res\audio r:\audio»
  5. Запускаем игру и наслаждаемся.
К стати, все эти пункты можно реализовать в одном батнике, а во втором — откат всего обратно.

Конечно, в этом всём деле важно не переборщить, чтобы объем файлов на RAM-drive не стал столь большим, что ОС решит задействовать своппинг — тогда вся идея летит к чертям. Но вот что вышло у меня:

Время обращения к файлам в папках на RAM-drive упало практически до нуля, карта стала грузиться намного быстрее, я стал появляться часто еще до начала предстартового отсчёта, успевать перекинуться парой фраз с союзниками перед началом боя. В общем, чего хотел — добился. Жаль всё-же что не довелось глубже покопаться в недрах игры и заюзать хуки — но зато мой способ не нарушает лицензионного соглашения WoT, что тоже немаловажно.
Владимир @tangro
карма
709,2
рейтинг 30,7
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

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

  • +7
    где вы раньше были… я же по этой причине играть перестал. наверно снова начну!)
    • +1
      так а толку? все равно таймер еще ждать.
      • +1
        Ага :) С 4gb в ноуте долго происходит только первая загрузка, потом файловый кэш в Win7 делает своё дело. Даже если из игры выйти и запустить чуть позже.

        2tangro: Хороший детектив, прочитал с удовольствием :) я думаю там дело в seek, т.к. файлы вероятно читаются не в порядке инсталляции (т.е. не в порядке размещения на жёстким диске) и это, скорее всего так же касается чтения кусков из «pak» fsb файлов в каталоге audio. Но это гипотеза :) и как такое ускорить через хуки — с ходу тяжело придумать…

        Есть идея отпрофайлить, в каком порядке это чтение чаще всего происходит и на основании этой информации сделать «дефрагментированную» пересборку файлов игры, куда потом и перенаправлять вызовы OpenFile/ReadFile. Метод, в принципе, довольно универсальный — может не только танкам пригодиться :)
  • +4
    Хм. То есть решением было бы ssd поставить, угу)
    • +4
      SSD != RAM-диск
      • 0
        Да, но он бы решил проблему с медленной загрузкой карт.
        К тому же не тешьте себя, настоящий «правильный» ram-disk бывает только в linux/unix. Так что ваше решение != RAM-диск тоже.
        • +1
          «Настоящий правильный RAM-диск» — в смысле такой, который никогда не будет выгружен в своп? Или что?
          • +1
            В смысле который /dev/shm — может монтироваться куда угодно, быть частью RAID1 (нам же ведь чтение нужно быстрое, а запись может и подождать, зато данные будут в сохранности). И вообще может выступать полноценным блочным устройством, а не виртуальным огрызком.
            • +7
              Монтироваться куда угодно может и junction в Windows — в любую папку.
              Не могу понять, зачем в данной ситуации зеркало. Зеркало нужно, чтобы ускорить чтение, поделив его между двумя дисками. Тут RAM все равно будет быстрее, чем диск. Запись никакая в этом сценарии не нужна.

              Лучше всего было бы сделать так: сделать в RAM копию данных и выкинуть ее, когда у нас будет мало памяти. О черт, это называется файловый кеш, он в Windows есть, и если взять версию не десятилетней давности, а какую-нибудь поновее, где он лучше работает, то все будет работать без RAM-диска. Что же получается? Не нужен RAM-диск, не нужен RAID1, не нужен Linux — все работает и так…
              • +1
                Зеркало нужно для того, чтобы данные всегда писались на диск, если изменятся.
                И да — файловому кешу нередко сносит башню, так что он здесь совсем не подходит. Например, просмотр фильма тяжелого вполне может выкинуть все файлы системы из памяти.
            • 0
              не вводите людей в заблуждение, /dev/shm (tmpfs), не является полноценным рамдиском, и запросто может попадать в своп.
              настоящий ramdisk это блочное устройство(/dev/ram0, например), созданное из выделенного фрагмента оперативной памяти, которое можно отформатировать в любую желаемую файловую систему.
              • –1
                swapiness для кого придуман?
                • 0
                  Смешались в кучу люди, кони…

                  vm.swapiness придуман не для того, чтобы какой-то определенный фрагмент памяти запретить свопить. Он не умеет этого делать. Он указывает system-wide политику свопинга и ничего более.

                  А дальше действует стандартный своппер, просто его агрессивность и порог срабатывания будут другими.

                  Можно, конечно, выставить там 0 или вообще сделать swapoff -a (и да, получить гарантию от свопинга), но это не решение (т.к. ненужные данные в своп не попадут тоже, втупую забив память и не позволяя адекватно работать дисковому кэшу в памяти) во-первых и ведет к непредсказуемым глюкам в случае жесткого oom во вторых.
            • 0
              shared memory совсем для другого создан.
        • +2
          Решил бы, но вопрос цены и наличия этого SSD в компьютере. Каждому решению свое место, в данном описанном случае выгрузить в оперативную память часть компонентов — было очень хорошим решением на мой взгляд.
      • 0
        Упс, извиняюсь, не ваше, а автора.
  • +2
    Начиная с висты можно было заюзать софтлинки вместо junction.
    Ну а насчет нарушения соглашения — строго говоря вы же не вмешиваетесь в работу игры, а вмешиваетесь в работу системы (если править таблицу экспорта или использовать сплайсинг, вместо хука IAT).
    То есть модификации идёт в памяти системных библиотек, а не файлов игры.
    • 0
      Там весьма мощное соглашение. Хуки вполне подпали бы под какое-то «изменения алгоритмов работы» и т.д.
      • 0
        Ну я не юрист, но, прочитав здесь, не вижу никаких сложностей.
        Краем задевает только пункт 4.4: «не модифицировать Проект».
        «Проект — Игра + Пользователи + Модераторы + Администрация.»
        «Игра — Программа + Сайт + Контента + Материалы»
        «Программа — компоненты программного обеспечения, как отдельные, так и в совокупности, размещенные Администрацией или Разработчиком на Сайте, на сайтах третьих лиц в сети Интернет, DVD дисках и других носителях информации, и специальным образом отмеченные как составные части «World of Tanks».»

        Собственно не вижу каким образом какой-нибудь kernel32.dll или ntdll.dll вписывается в эти определения.
        Ну и алгоритмов тоже упоминания не встретил.

        PS: ерунда у них, а не мощное соглашение, видно что писали по большей части программисты, а не юристы :)
  • +1
    Интересно: аудио 200 мб, всего 16 файлов, а грузится дольше всех — 14.48 сек…
    • 0
      Может, декомпрессия какая?
    • 0
      Каждый раз по-разному. Иногда аудио 14, а компоненты — 8, иногда аудио 8, а компоненты 25. Может от карты зависит или еще от чего-то.
  • 0
    tangro, какая у вас ОСь?
    • –2
      Судя по скриншотам, XP
      • +1
        ага, DOS. :)

        Win 7, просто с отключенным Аеро.
        В этом месте предполагалась подколка на счёт неполного использования 4 Гб памяти в 32-битных системах?
        • 0
          Ммм, нет. Никаких подколок. Просто предположил :)
  • 0
    Творения Руссиновича, как обычно — лучшие.
  • 0
    Недавно купил SSD и поставил WOT на него. Теперь появляюсь на карте одним из первых, и очень часто самым первым.
    • +4
      У меня обычный синий WD (не SSD). Появляюсь тоже первый :)
  • +11
    Use Windows Vista/7. С таким объемом оперативки кеш винды сделает ровно то же самое на автомате.
    • 0
      Первый раз после запуска игры карта всё равно долго грузится. Но вот потом да, мгновенно.
    • 0
      А вот не делает. Пробовал раз 5 подряд входить в бой — иногда быстрее, а иногда всё-равно время доступа к отдельным папкам очень большое. А в моём способе есть определённый детерминизм.
      • 0
        После кучки боёв на картах и большого (в моём случае это 8 гиг) объема оперативы кеш карт не вылетает оттуда в течении нескольких суток. Всё зависит от объема свободной оперативы ^_~
        • 0
          ну, я уже писал, что у меня ОЗУ меньше. может быть причина в этом.
    • 0
      Не сделает. Точнее, в идеальных условиях свободной памяти и чистого кэша — сделает, да. В реальной работе (с кучей фоновых приложений, в т.ч. работающих с диском) — эффект будет куда менее выражен.
  • +1
    То же самое в обязательном порядке делается с игрой Lineage2) Только там защита блокирует сторонние программы мониторинга (встроенный монитор ресурсов Windows работает отлично). Больше всего в Lineage2 клиент мучает папочку SysTextures, ее я и перенес на рамдрайв) После пробы разных рамдрайвов остановился на Dataram RAMDisk — при загрузке системы монтирует образ, при выключении системы сохраняет образ (для MMO игр это очень актуально, ибо данные постоянно обновляются), а главное нет проблем со спящим режимом)
    • НЛО прилетело и опубликовало эту надпись здесь
  • +17
    Ускоряем загрузку вашего топика на хабре:
    — Фотку танка не сохраняем в формате без потерь качества PNG.
    — Скриншоты не масштабируем, чтобы не увеличивать энтропию.
    — Такие бесцветные картинки можно и в 8 битих сохранять.

    тыц тыц тыц тыц тыц
    Меньше ваших в 4 с лишним раза.
    • +1
      Спасибо, чего уж там — и вправду так лучше.
  • 0
    В общем, нужно использовать современную операционную систему, а не ОС десятилетней давности.
    4 Гб вполне годятся, чтобы обновиться до Windows 7.
    Это не так и дорого, а все то же самое вы бы получили без RAM-дисков.
    • 0
      Да и на 2 гб чувствует себя 7 достаточно хорошо.
      Обновить надо.
      Но рам диск все равно ускоряет загрузку нужных файлов.
      • 0
        К тому же, можно купить копеечную флешку на 4-8Гб, и заюзать ReadyBoost.
        В таком случае, даже 2Гб для 7ки будет достаточно.
  • +2
    вообще есть другая идея для ускорения, не жертвуя ОЗУ.

    это использование утилитки, которая дает план загрузки файлов (как в этой статье), а дальше использование mydefrag, для создания областей на диске в которых в определенном порядке лежат файлы. Это ускоряет не меньше.

    Сейчас и oo defrag чем то подобным распологает, но не так гибко настраиваемо, как в mydefrag.
    например есть скрипт для WoW под mydefrag, после этого, вы сразу почуствуете, скорость загрузки WoW(world of warcraft).
    • 0
      Если бы вы написали точнее, то был бы крайне признателен.
      • +1
        Тут
        скрипт. прогу тоже берешь и в путь.
        чтобы придумтраь скрипт, нужно почитать хелп и посмотреть примеры других скриптов.
        дляэтого скрипта лучше, когда wow на отдельном разделе диска. так как дефрагментацию надо производить с каким то периодом, и это будет быстрее, чем на смешанных данных.

        вообще это скрипт, не только грузит wow быстрее, но и убирает лаги в прорисовке сцен.
        • 0
          Спасибо, если не поленюсь — попробую на WoT
  • 0
    Хм, у меня все резво загружается с обычного hdd. А для начала дефрагментировать диск не пробовали. Таким образом, чтобы все файлы в папке лежали в одной куче, а не по всему диску были раскиданы.
  • –1
    Мне для достижения приемлемой скорости загрузки достаточно оказалось поставить винт WD Caviar Black. Хотя исследование, безусловно, интересное.
    • 0
      Аналогичный винт стоит, 100мбит/сек выдает, и ресурсы все сдефрагментированы, грузится очень быстро )
  • 0
    Какой то геморой… обычно первый загружаюсь и без него. И винт не ссд и инет «гавно». А в общем всё равно ждать придётся всех остальных. А движок кончено у них изначально был старый и то что он до сих пор справляется как раз заслуга не кривых рук программистов.
  • –3
    Хм, у меня стоит Win 7 pro 64-bit, 8Gb оперативки и я загружаюсь быстрее всех, без всяких танцев с бубнами…
    • 0
      ах да, диск родной от ноутбука (hp probook 4520s) 5200 Об./минуту.
  • –2
    У них движок ппц тормозной.
  • +1
    Link Shell Extension — по моему опыту самая удобная утилита с гуем для создания ссылок в win:
    schinagl.priv.at/nt/hardlinkshellext/hardlinkshellext.html
    • 0
      угу, тоже сразу о ней подумал, когда начал топик читать.
  • +1
    Хабр торт — спасибо автору за статью!
    Офтоп: неужели в WOT(не играл) есть Меркава?
    • +2
      Нет там меркавы. И абрамса нет. Танки только 20-х-50-х, большая часть — времен второй мировой.
  • 0
    Может я что-то упустил, но есть же команда mklink (вроде). Позволяет создавать символические ссылки в windows (с какой версии — не помню). Пользовался ей для таких же целей.
    • –1
      Команда mklink появилась в win7 насколько я знаю, а у автора ХР.
      • 0
        Тогда прошу прощения.
      • 0
        У автора Win 7.
        • 0
          Ну вообще да, у автора Win7, но я хотел описать способ, который работал бы и на XP.
  • 0
    А мне наоборот нравится что танки у меня грузятся секунд 15-25.
    А то появляешься первым на карте и сидишь ждёшь остальных.
    • +2
      Тогда вы можете использовать данный способ, но вместо рам-диска — флоппи-дисковод, подключенный по COM-порту. Никого ждать точно вам не придется.
  • 0
    11г весит? Почисти папку с апдейтами и у тех у кого 8г оперативки — все влезет на рам диск
  • 0
    По Alt+F6 в FAR Manager давно умеет «hard links for files, junctions for folders and symbolic links for files and folders»
  • +3
    Нафига такие заморочки?
    На форуме игры есть пережатые ресурсы игры. Причем с разной степенью сжатия.
    На глаз разницы в качестве графики не заметно, а ускорение не только загрузки, но и ФПС в самой игре поднимает.
  • 0
    Данные сжаты? Если нет, то может сжать папку с помощью NTFS compression и сделать дефрагментацию?
  • 0
    Ну так ведь все равно приходится ждать столько же времени как и раньше! Разве что поговорить можно до окончания отсчета…
  • –1
    Покупайте SSD и будет вам счастье, у меня секунд за 10 загружается любая карта
  • 0
    Эх… Сначала я купил дорогую видюху, но как оказалось, это не помогло.
    Проблему с долгой загрузкой я решил переносом игры на второй винчестер — не знаю всего механизма, но скорость загрузки увеличилась раза в два. Возможно потому что временные файлы на одном винте, а читаются файлы с другого винта.

    А вот как решить проблему при игре на ноуте — не знаю. У меня Lenovo y430, c2duo, 2G ram, и там стоит видюха жифорс 9300М. Параметры вроде хорошие, но 10-15 фпсов… Можно ли пофиксить?

    п.с. Игровой движок от БигВорлда — ужоснах. Там гигантское количество багов. Что бы его допилить надо гинатское количество кода переписать, и хаков применить.
  • 0
    Пожмите ресурсы, очень помогает. На форуме у них есть паки со степенью сжатия 50%, 25% и 12.5%. На не самых лучших настройках разницы не заметите. Заодно и ФПС повысите. Правила, я думаю, это не нарушает, иначе давно закрыли бы эту тему на форуме.
  • 0
    Пожмите ресурсы. На форуме игры есть тема с паками со степенью сжатия 50%, 25% и 12.5%. Ускоряет загрузку и ФПС игры. На не самых лучших настройках разницы не заметите.
    • 0
      … а чего это оно пишется так два раза, блин. обновлял ведь, смотрел.
  • 0
    На моем Acer Revo R3610 после (да и до тоже не напрягало) урезания текстур стало грузиться в считанные секунды. Правда, все выглядит, как картины Ван Гога и FPS максимум до 12 удалось поднять. Странный дизбаланс — на слабом компе у меня грузится быстрее, а в игре тормозит жутко.
  • +1
    MacBookPro Mid '10, Win 7: загружаюсь первым.
  • 0
    По вашей статистике из директории audio он прочитал чуть меньше 60 мегабайт в 33 файлах за 14.4 секунд. Думаю у вас просто была сильная фрагментация этих данных.
    • 0
      Вообще, описанный в статье случай — это что-то «из ряда вон». Обычно больше всего кушает папка «content» (и это видно на последнем скриншоте). Не знаю почему с аудио так вышло, может и правда фрагментация.
  • 0
    Глянул свой клиент, с перепаковаными текстурами он влезает на 2 ГБ РАМ диск с включенным НТФС сжатием(на распаковку плюем, проца все равно еще несколько ядер простаивающих).
    Оставшихся 2х гиг оперативки теоретически хватает для работы игры. На практике проверить не могу, траблы с соединением к серверу.
    По крайней мере на запуск клиента дисковых операций 0.3 сек вместо 20+ с винта.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.