Коротко о GPU Busy — новой метрике игровой производительности
Уже три года как тому назад читатели моего блога могли поближе познакомиться с очень важной метрикой игровой производительности, известной как время кадра, а так же узнать о свободной утилите PresentMon от Intel, способной эту величину измерять.
Сегодня Intel представила на суд общественности новую beta-версию утилиты PresentMon, в которой появилось много всего нового и интересного, например, вот такой красивенький конфигурируемый оверлей.
реклама
Оверлей — штука, безусловно, интересная и полезная, но мы обсудим другое не менее интересное и полезное нововведение, появившееся в новой версии PresentMon, а именно новую метрику производительности, названную разработчиками GPU Busy.
Для понимания сути этой метрики посмотрим на следующим слайд из видео с известного канала Gamers Nexus, в котором старший научный сотрудник Intel Том Петерсен (Tom Petersen) кратко объясняет смысл происходящего.
реклама
Итак, каким же образом генерируется всякий новый игровой кадр?
Вначале центральный процессор, получив необходимую информацию о действиях игрока от устройств ввода, выполняет вычисления, связанные с игровой логикой и физикой, чтобы получить полное математическое описание состояния игрового мира, которое нужно отобразить на экране. Этот этап отражён на рисунке выше синим прямоугольником Game в строке CPU.
Затем центральный же процессор выполняет вычисления, которые преобразуют полученную актуальную математическую модель игрового мира в команды некоторого графического API, которые и приведут в конечном итоге к рендерингу нового кадра. Этот этап отражён на рисунке выше синим прямоугольником Render в строке CPU. В конце этого этапа вызывается команда графического API на отрисовку нового кадра. В API Direct3D, например, это вызов метода Present().
реклама
И вот здесь происходит много всего интересного. Несмотря на то, что все необходимые команды для отрисовки нового кадра уже собраны, передавать их напрямую в графический процессор бессмысленно, так как языка этих команд он попросту не понимает. Сначала управление передаётся библиотекам, реализующим API, которые переводят команды этого API в команды, понятные драйверу графического ускорителя. Затем драйвер графического ускорителя переводит эти ему одному понятные команды в инструкции, которые наконец-то может исполнять уже непосредственно графический процессор, и вот эти инструкции и передаются непосредственно графическому процессору. И всё это время, игра не может начать просчитывать следующий кадр на центральном процессоре, так как вынуждена ждать, пока будут выполнены все описанные выше преобразование команд графического API в инструкции графического процессора. Кроме того, перед отправкой инструкций графическому процессору может понадобиться подгрузить из основной памяти какие-то текстуры или скомпилировать какие-то шейдеры.
Весь этот этап подготовки инструкций и данных для графического процессора с точки зрения игры отражён на рисунке выше синим прямоугольником Wait в строке CPU. Обратите внимание, что центральный процессор в этот момент, конечно же, не находится в каком-то режиме ожидания, он вполне себе загружен, ведь именно он выполняет указанные выше преобразования команд графического API в инструкции графического процессора, а так же, возможно, загрузку текстур и компиляцию шейдеров. Но вот игра как раз вынуждена ждать окончания этого процесса, прежде чем начинать вычисления Game и Render уже для следующего кадра.
Как только последовательность инструкций графического процессора, соответствующая командам графического API, необходимым для рендеринга кадра, готова, она посылается графическому процессору. И тот уже попросту выполняет все необходимые для рендеринга кадра вычисления. Этот этап отражён на рисунке выше синим прямоугольником GPU Render в строке GPU.
Это, безусловно, очень упрощённая схема работы графического конвейера, но уже её достаточно для того, чтобы понять одну простую истину — время кадра, отсчитываемое по временным отсечкам вызова метода Present(), плохо отображает сколько времени на рендеринг потратил именно графический процессор. А ведь здесь возможны различные неприятные с точки зрения итоговой игровой производительности ситуации, в которых графический процессор по факту не виноват.
реклама
Например, возможно, что последовательный перевод команд графического API в команды драйвера, а затем в инструкции, понятные графическому процессору, будет занимать очень много процессорного времени. Такое, кстати, отнюдь не редкость. Это те самые пресловутые накладные расходы API и драйвера (API и driver overhead), о которых многие уже слышали и слышали не один раз. А возможно, в игре не лучшим образом реализован механизм подгрузки текстур или компиляции шейдеров "на лету", так что прямоугольник Wait растянется ещё сильнее.
Все эти процессы могут сильно увеличить время кадра, но вины графического процессора в этом нет. И теперь появилась возможность определять такие неприятные ситуации, используя новую версию PresentMon, которая способна теперь измерять не только время кадра, но и время непосредственной работы графического процессора в ходе рендеринга кадра.
Вот так, например, выглядел график времени кадра (голубой), посчитанного по временным отсечкам вызова метода Present(), и времени работы собственно графического процессора (жёлтый) в игре Overwatch 2 на системе с Core i5 13400F + Arc A750 и релизной версией драйверов Intel. В идеальном случае, как, например, в выделенной области в центре, эти графики почти повторяют друг друга. Да, время кадра, конечно же, чуть больше, так как в создании кадра принимает участие не только графический, но и центральный процессор, но больше оно лишь на некоторую незначительную и практически постоянную величину.
А вот в выделенной области слева ситуация, мягко скажем, неидеальная — графический процессор со своей задачей справился примерно так же быстро, как и в области в центре, но центральному процессору пришлось сделать заметно больше работы. И как итог время кадра на этом отрезке оказалось заметно выше. Конечно, не факт, что это произошло из-за того, что накладные расходы API или драйвера на этом участке оказались выше, или из-за того, что понадобилось загрузить какую-то текстуру или скомпилировать шейдер. Возможно, например, что в этот момент в игре произошло разрушение большого количества объектов виртуального мира, и время кадра оказалось большим из-за более долгого обсчёта физики. Но такие области, где наблюдается резкий контраст между временем кадра и временем работы графического процессора требует более детального изучения.
Например, в случае с Intel достаточно взглянуть на результаты той же самой системы в той же самой игре на том же самом тестовом отрезке только с более поздней версией драйвера, чтобы убедиться, что дело таки было в накладных расходах драйвера, которые удалось заметно сократить.
Важно так же отметить, что Intel нарочно использует здесь не самый быстрый центральный процессор (Core i5 13400F), а не что-то более монструозное. И сделано это не только, и даже не столько, потому, что видеокарты уровня Arc A750 вряд ли можно будет встретить в реальных сборках с чем-то более мощным, чем Core i5, а потому, что топовые процессоры за счёт своей огромной вычислительной мощи банально способны справится со всеми задачами настолько быстро, что негативные эффекты от накладных расходов API и драйвера + не самые удачные решения по загрузке текстур и компиляции шейдеров "на лету" будут как-бы "скрадываться".
Возможна, впрочем, и обратная ситуация, когда попросту недостаточно мощный процессор не способен преодолеть указанные выше преграды на пути к меньшему времени кадра, а мощный графический процессор никак не способен повлиять на конечный результат. В общем, внезапно, во всём оказался важен баланс! И здесь мы уже находимся в шаге от вступления в секту "раскрывателей". Поэтому нам нужно быть предельно осторожными.😁Впрочем, теперь то у нас есть научный подход к этому вопросу и даже готовая утилита для необходимых замеров.
Итак, в хорошо сбалансированной системе хорошо оптимизированная игра, использующая API и драйвер с небольшими накладными расходами, должна демонстрировать картину производительности примерно как на графике выше. Да, время кадра (по определению) должно быть больше времени рендеринга кадра графическим процессором, но больше на небольшую и желательно постоянную величину.
Лента материалов
Соблюдение Правил конференции строго обязательно!
Флуд, флейм и оффтоп преследуются по всей строгости закона!
Комментарии, содержащие оскорбления, нецензурные выражения (в т.ч. замаскированный мат), экстремистские высказывания, рекламу и спам, удаляются независимо от содержимого, а к их авторам могут применяться меры вплоть до запрета написания комментариев и, в случае написания комментария через социальные сети, жалобы в администрацию данной сети.
Комментарии Правила