reported by CCP Veritas | 2011.02.07 19:45:05
оригинал
Привет. Спасибо что оторвались от битвы с саньшей чтобы взглянуть на этот девблог. Он посвящен ракетам, процессорам и всему такому.
Вначале я хочу сказать, что все описанные изменения еще не реализованы на транке. Мы собираемся вводить эти изменения по одному, следить за эффектом и в зависимости от результатов включать один элемент и переходить к другому. По этой причине у нас нет четкого расписания, но скорее всего первые эффекты изменения вы сможете заметить в больших сражениях начиная с четверга. Возможно в результате тестирования окажется что данные изменения работают не так как ожидалось и тогда мы не будем их вводить. Тем не менее я решил что сами по себе результаты будут интересны, но имейте в виду вышесказанное.
Ракеты
Как уже говорилось в предыдущих девблогах (1 , 2 ), ракеты обходятся недешево. CCP Masterplan провел замечательную работу по их оптимизации в Destiny (физический движок EVE), но ракеты все еще остаются достаточно ресурсоемкими по сравнению с другими видами оружиияя, так что мы продолжили разбираться в проблеме.
Чтобы понять, почему именно ракеты требуют больше ресурсов, чем, скажем, лазеры, посмотрим что именно надо сделать при активации ланчера:
Добавить физический объект (шар) в симуляцию
Добавить объект в инвентарь солнечной системы
Добавить объект в движок Dogma (отвечающий за активацию модулей и рассчет характеристик объектов)
Промоделировать полет ракеты через пространство для определения столкновения с целью
Взорвать ракету
Удалить объект из Dogma, инвентаря и физической симуляции
В общем, много всего. Часть этих операций относительно дешева в вычислительном плане (например, совершенно неожиданно, симуляция полета), часть достаточно ресурсоемка (например, работа CCP Masterplan значительно уменьшила нагрузку от этапа «добавить физический объект в симуляцию»). И все это нужные полезные вещи, позволяющие игроку убежать от ракеты или убить ее смартбомбой или дефендером.
Мы потратили какоето время рассматривая по очереди все эти операции на предмет возможной оптимизации. И обнаружили много интересного.
Запрос на проверку имеет ли персонаж необходимые навыки для запуска ракеты проводился дважды.
Запрос модификатров каждого атрибута ракеты за счет навыков ароводился дважды
Были убраны старые забытые функции которые не использовались уже несколько лет
Каждая ракета инициализировалась полным набором данных для NPC ИИ. Практически все они не использовались и теперь убраны из инициализации.
Многие подсистемы движка обрабатывали взрыв ракеты точно также, как взрыв корабля. Исправлено.
Изменен алгоритм рассчета урона от ракеты, так что теперь нужные даные не запрашиваются, пока в них не возникает необходимость
Кроме того, это небольшое исследование привело к двум значительным изменениям.
Поддельная Догма для ракет
Раньше при запуске ракеты (или, благослави вас бог, группы ракет) в движке Dogma для нее создавался новый объект. Поскольку это был новый объект, его атрибуты были не определены и при каждом запросе атрибута, запрос, естественно, промахивался мимо кэша и вызывал полный набор рассчетов. Эта операция занимает примерно 0.08 миллисекунды, что в общем то не очень много, если забыть что у каждой ракеты 10 атрибутов,а в гирде несколько сотен ракет.
Главный момент здесь следующий – ракета в космосе имеет точно такие же атрибуты как и ракета в ланчере. Так что мы можем просто скопировать известные атрибуты ракеты-в-ланчере для нашей свежесозданной ракеты-в-космосе и больше не делать для нее никаких дополнительных вычислений внутри Dogma. Поскольку ракеты-в-ланчере не имеют индивидульного индентификатора, то все сводится к запросу типа ”вот те ракеты в вон том ланчере”, результат которого будет оставаться одним и тем же между запусками ракет, так что мы можем рассчитать атрибуты один раз и пользоваться ими до тех пор, пока не поменяем тип патронов. Такой подход также значительно повлиял на время, необходимое для запуска и взрыва ракеты, поскольку инициализация и уничтожение этих неполных ”поддельных” объектов происходит намного быстрее.
Инвентаризация
В процессе тестирования вышеописанных изменений я обнаружил, что со временем производительность немного падает. Сравнив результаты работы Telemetry в начале тестирования и в конце, я обнаружил, что основная разница заключается в работе кода, удаляющего ракеты из инвентаря солнечной системы. Это определенно имеет смысл, но выглядит не радостно. В процессе тестов я я создал и убил множество кораблей и оставил в системе кучу мусора. Если скорость обработки инвентаря системы до такой степени зависит от количества объектов в космосе, то чтото тут неладно.
Так оно и оказалось. Впереди техническая мумбаюмба
Когда мы делаем запрос к базе данных, мы получаем результат в виде структуры данных, прозводной от структуры List (список) в Python. Эта структура реализована в виде массива указателей на значения элементов. Такой подход практически идеален для большинства случаев, поскольку в результате мы получаем упорядоченный список строк базы данных и ничего в нем не менеям.
В случае инвенторя дело обстоят по другому. Мы получаем ответ на первоначальный запрос к базе в виде списка, но затем мы этот список изменяем и при этом не особо заботимся об упорядоченности. Добавление объектов к списку оносительно дешево, новый элемент просто довавляется в конец. Но вот поиск и удаление просто неописуемо ужасны. Поскольку список не имеет индекса и возможностей сортировки, поиск элемента для изменения линеен. Удаление элемента, соответственно, включает в себя сначала линейный поиск этого элемента, а затем копирование всех последующих элементов на одну позицию выше. Обычно зависимость вида O(n) это знак завершения работы, но в данном случае это признак больших проблем.
Решение оказалось ужасно простым – заставить систему инвентаря запрашивать структуру "set" вместо структуры ”list”. В коде оказалось всего несколько мест где инвентарь рассматривался явно в виде списка и мы их быстро починили. Результатом оказалось очень заметное увеличение количества ракет, обрабатываемых сервером в секунду. Также есть надежда что это приведет к общему увеличению производительности, поскольку инвентари используются во многих частях игры.
Довольно слов, я хочу красивую картинку!
Методология: для получения этой картинки я заставил 200 кораблей стрелять в хакерско-читерский дрейк. Скорость стрельбы была искуственно поднята до тех пор, пока обработка полностью не загрузила сервер, после чего я записал скорость срабатывания модулей на ноде и усреднил ее за 60 секунд стабильной работы.
tl;dr: Речь идет от пятикратном уменьшении загрузки от ракет. Ракеты все еще остаются более ресурсоемкими чем пушки, но уже в разумных пределах. Надеюсь эти изменения облегчат жизь пилотам после того как пройдут тестирование и будут реализованы на транке.
Счастливых полетов, мои друзья-дрейкофилы,
~CCP Veritas
Сообщение отредактировал Tester128: 08 February 2011 - 18:23