Почему для управления ресурсами необходимо настраиваемое управление памятью?


10

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

Однако на ПК ситуация совсем иная. ОС предоставляет виртуальную память для системной памяти, а графический драйвер выполняет переключение между процессором и графическим процессором. Так почему же недостаточно загружать все сразу, а иметь дело только с предварительной загрузкой и, возможно, с тем, чтобы убедиться в отсутствии блокировок во время замены необходимого актива?


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


ОБНОВИТЬ:

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


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

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

Вы уверены, что это имеет отношение к вашему игровому проекту? Я не уверен, что вижу техническую проблему, только решение. Если вы не сталкиваетесь с технической проблемой, трудно адаптировать решение или понять его.
AturSams

Мне интересно, почему игровые движки реализуют сложные системы кэширования ресурсов, когда операционные системы / драйверы уже имеют системы виртуальной памяти. Это актуально для меня, потому что я пишу игру с открытым миром, где эта информация очень важна.
jmegaffin

Ваша игра страдает от проблем с производительностью, а инструмент профилирования показывает, что это из-за доступа к памяти? Проблема с играми, которые содержат открытые уровни, заключается в том, что в техническом плане это приводит к большому количеству данных. Чем больше у вас контроля над этими данными, тем выше будет производительность. Почему бы не внедрить наиболее эффективную систему управления данными? Разработка игр очень конкурентоспособна, и, когда у вас есть деньги на экспертов, вы не оставите камня на камне, стараясь выжать больше деталей и увеличить количество кадров в секунду.
AturSams

Ответы:


16

Современные игры с открытым миром просто не умещаются в памяти. Имейте в виду, что большинство игр по-прежнему 32-разрядные из-за количества игроков с 32-разрядными ОС, и 32-разрядный процесс в лучшем случае может иметь только 4 ГБ адресуемой памяти одновременно (независимо от виртуальной памяти), но реально ограничено 2-3 ГБ. Бросьте фрагментацию и фактическое количество пригодных для использования объектов, которые вы можете иметь в памяти за один раз, немного меньше, чем общее количество данных, необходимых для большой среды. Даже в 64-битной ОС вам часто приходится ориентироваться на машины с низкой спецификацией, имеющие только 4 ГБ памяти, чтобы обеспечить максимальную совместимость с конечным пользователем. Давайте не будем забывать о мобильных устройствах, «недостаточно мощном» оборудовании, таком как WiiU и т. Д. Разработчики должны стремиться к гораздо большему, чем просто модные игровые ПК.

Виртуальная память не является решением, во-первых, потому что она не отменяет ограничения адресного пространства, а также потому, что она не оптимальна. ОС может выкладывать вещи в неподходящее время или неподходящим образом. Это была проблема, с которой сталкивались ОС, когда впервые появился спящий режим; распаковка процессов на диск и последующая их подкачка в некоторых случаях были значительно медленнее, чем при явной передаче приложением явного потока ресурсов обратно. Сегодня вы можете увидеть проблемы, когда системе не хватает памяти, страницы выгружаются на диск, и система перестает отвечать на запросы, становится критически важной вещью, необходимой для запуска вашего WM / explorer.exe. Виртуальная память была решением проблемы, разработанной десятилетия назад, когда в системах было очень мало оперативной памяти, а разрыв между скоростью памяти и диском был намного меньше. Даже сегодня' Самые быстрые твердотельные накопители - это небольшая доля скорости дешевой / медленной оперативной памяти, и попытка сделать вид, что вы можете использовать свой диск в качестве виртуальной оперативной памяти, больше не лучшая идея. Это эпоха, когда некоторые люди делают наоборот и загружают файловые системы на диски RAM; ограничения, которые привели к созданию виртуальной памяти, больше не выполняются.

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


Спасибо за подробный ответ. Хотя я все еще ищу некоторую информацию о том, как драйверы графического процессора обрабатывают виртуальную память (между VRAM и системной RAM).
jmegaffin

@Boreal: те же проблемы. Просто замените «RAM» на «VRAM», а «disk» на «CPU memory»
Шон Мидлдич

@SeanMiddleditch +1 Хороший ответ: «Это эпоха, когда некоторые люди делают обратное и загружают файловые системы в диски RAM», вы имеете в виду файлы с отображением в памяти? Из вашего ответа я также понимаю, что пользовательский распределитель памяти не позволяет ОС выгружать память, не так ли это, поскольку память будет выгружаться настолько, насколько вы запрашиваете память у ядра, например, с помощью brk (), как пейджинг на ПК точно предотвращается с помощью пользовательского распределителя памяти?
concept3d

1
@ concept3d: не отображение памяти, а буквальные RAM-диски. Вы можете создать диск, который поддерживается памятью, а не диском. Пользовательский менеджер памяти не предотвращает подкачку страниц (какое-то другое приложение может использовать всю память). Интеллектуальное управление ресурсами (на уровне управления объектами / ресурсами) просто означает, что вы освобождаете память для объектов, которые вам больше не нужны. Подумайте о дисковых кешах операционной системы, которые она хранит в памяти
Шон Мидлдич

6

Для 32-битной игры, поскольку большинство игр по разным причинам, даже игра, которая поставляется на одном одностороннем DVD (4,3 ГБ), уже имеет гораздо больше контента, который можно вписать в 32-битное адресное пространство. И это при условии, что контент не сжимается на диске и является совершенно оптимальным, загружая все сразу в подход непрерывного адресного пространства. Многие игры теперь поставляются на нескольких DVD, легко превышая 10 ГБ контента. По моему опыту работы с ПК, когда ваше адресное пространство приблизится к 2 ГБ, выделение начнёт давать сбой, и это станет жестким ограничением, независимо от того, сколько физической памяти у пользователя.

Если вы перейдете на 64-битный режим, предполагая, что ваш движок его поддерживает, этот жесткий предел исчезнет, ​​и его заменит эффективный мягкий предел - как только произойдет перестановка виртуальной памяти, производительность игры упадет. недопустимо. Если главному процессу когда-либо придется ждать, пока память будет выгружена обратно, частота кадров будет зависать и сбиваться. Виртуальная память может сделать это прозрачным, но это не делает его производительным. Физически требуется время, чтобы вернуть эту память с диска, и пока вы ждете, ваша игра остановилась. Хотя можно обойти это (с предварительной выборкой страниц памяти в фоновом режиме, которая, как вы знаете, скоро понадобится), это сложный и ненадежный процесс, который по-прежнему будет влиять на производительность.

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

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

  1. Ваша игра загружается и переходит в интерактивное состояние намного дольше, чем нужно, потому что она просто загружает все в начале и сохраняет ее резидентной. Вы можете загрузить около 150 МБ / с с жесткого диска, и даже самый быстрый DVD-привод (24x) загружается со скоростью 33 МБ / с. Это означает, что пример содержимого DVD объемом 4,3 ГБ займет не менее 30 секунд для загрузки с жесткого диска и более 133 секунд для загрузки с DVD. Это недопустимо долгое время загрузки.

  2. Ваша игра занимает гораздо больше памяти, чем оправдано. Если в любой момент времени видно только 10% контента, удержание остальных резидентов просто расточительно и не позволяет пользователю использовать эту память для чего-то другого. Пользователи, как правило, не прощают игры, которые требуют непропорционально большого объема памяти для правильной работы.

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


1

Говоря просто в общих чертах и ​​упрощенно, и без учета деталей реализаций виртуальной памяти, разработчик всегда заранее знает, чего не хватает реализации виртуальной памяти.

Разработчик всегда может сказать: «Мне не нужно загружать этот аудиофайл прямо сейчас. Музыка внутри используется только для игры поверх экрана». И сразу же после выхода игры за экран, разработчик может сказать: «Мне больше не нужен этот аудиоклип в физической памяти. Он используется только для этой игры поверх экрана».

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

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

Говоря еще шире, существует бесконечный цикл между разработчиком оборудования, разработчиком компилятора, разработчиком ОС / драйвера и разработчиком приложения. Разработчики оборудования / компилятора / ОС / драйвера часто пытаются реализовать оптимизацию для ускорения вашего среднего приложения на основе его обычных шаблонов доступа к памяти, и, возможно, иногда с такой надеждой: «Люди должны просто иметь возможность писать код так, как им хочется, и это должен быть быстрым. "Но если кто-то думал об этом типе, он обычно терпит неудачу в критических по производительности полях, потому что тогда разработчики, критичные к производительности, начинают изучать сложные детали своего компилятора, аппаратного обеспечения, ОС, драйверов и т. Д. И начинают писать код специально Предназначен для максимально возможного написания максимально быстрого кода (например, предварительных выборок, расщепления горячих / холодных полей, SoAs и т. д. для кода, удобного для кэширования). И это как игра, которая никогда не заканчивается. Эти вещи никогда не рассматриваются как черные ящики в областях, критичных к производительности, поскольку разработчики конкурируют за производительность.

Лично я бы хотел, чтобы виртуальная память не существовала, поскольку она добавляет дополнительный уровень непредсказуемости производительности способами, которые являются чрезмерно экстремальными и приводят к значительным потерям производительности, когда дела идут на юг, вплоть до непригодности., Я иногда сталкивался со случаями, когда я использовал какое-то приложение, в котором я случайно набрал лишнюю цифру или две, когда выпил в какое-то поле ввода, что затем приводило к такому быстрому истощению физической памяти, что приводило ОС к ползанию, где я не мог Я даже больше не нажимал кнопку «Отмена» на индикаторе выполнения, и ему пришлось ждать 10 минут, нажимая Ctrl + Alt + Del, чтобы остановить процесс, и проклинать себя, выплескивая свой напиток, чтобы вернуться к точке, где вещи снова можно использовать, и это несмотря на то, что файл подкачки хранится на SSD. В тех случаях, я бы скорее предпочел «из памяти» ошибку или что-то, и в этот момент я мог бы закрыть некоторые из моих 17 вкладок порно (это нормально, я закладка моих любимых во всяком случае), чтобы освободить память, а затем немедленно идти о возобновить мой бизнес.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.