Измерение производительности видеосистемы: практика (страница 4)
Эмуляция реальной частоты кадров на Fraps-Calc
У некоторых программ есть возможность подсчитывать скорость кадров и формировать лог «Frametimes» в виде списка времени получения сигнала окончания рисования. Способ полезный, он дает возможность получить больше ценной информации об игровом процессе и оценить производительность компьютера. Но такое впечатление создается только при поверхностном взгляде, в действительности все сильно запущено. Дабы не рассуждать об абстрактных понятиях, возьмем широко известную программу FRAPS и сразу засунем нос туда, куда не просят – в ее внутренности.
Для измерения производительности программа FRAPS перехватывает выполнение команды «Present», выдаваемую в конце каждого кадра как сигнал о конце «рисования» процессором и передаче «сырого» кадра для дальнейшей обработки графическим процессором видеокарты. При этом программа может выполнять графический вывод на экран или «захват» содержимого для выполнения снимка или записи видеофрагмента. Все эти действия удобно производить до выдачи признака об окончании рисовании, т.е. до прохождении «Present» из игровой программы в DirectX. Собственно, «там же» и находится место снятия времени получения кадра. Мне сложно объяснить побудительные мотивы размещения измерения в этом месте, но так сделано.
Альтернативный вариант? Можно взять время на момент выхода из обработчика DirectX. Различие в том, что время «входа» не представляет ничего ценного. Игра формирует кадр, на что тратится какое-то время, после чего индицирует об окончании рисования и по этому признаку снимается время «чего?». Да ничего осмысленного. Сформированные данные о кадре еще будут обрабатываться в видеокарте и лишь затем полностью готовый кадр отобразится на «Front buffer».
Ну хорошо, а чем же лучше «выход» из обработчика «Present»? Давайте немного помедитируем над работой с кадрами. Процессор должен сформировать описание кадра, которое «складывается» в блоки, в одном блоке описание одного кадра. Внутренне представление в драйвере (и видеокарте) может различаться, но суть всегда остается одинаковой – существуют блоки описания каждого кадра и количество таких «ячеек» ограничено. У фирмы NVIDIA используется понятие «Pre-Rendered Limit», AMD - … ничего не использует, эта настройка сгинула из панели управления.
реклама
Неважно, в любом случае драйвер готов принять не более некоторого числа кадров на обработку. Если центральный процессор способен формировать кадры быстрее, чем способна обработать видеокарта, а это выполняется почти всегда, то вся очередь «заготовков» кадров оказывается забита и поступление нового кадра возможно только в случае освобождения одной из ячеек очереди – пока не обработается (и скопируется на экран) какой-то кадр. Во время обработки команды «Present» DirectX выполняет некоторые действия по окончанию работ с данным кадром, после чего возвращает управление и игра может начинать строить новый кадр.
Одно «но» - ‘во что’ строить? Если DirectX не позаботится о наличии хотя бы одного блока для формирования нового кадра, то наступит полный крах – данные «перельются через край». Дабы избежать такого сценария, DirectX (скорее «драйвер») задерживает возврат из функции до тех пор, пока не освободится блок. Современные компьютеры достаточно производительны и очередь заданий по кадрам всегда оказывается полной. Как итог, «вход» в обработчик «Present» и «выход» из него – это две большие разницы.
Первое ничего осмысленного не представляет, зато второе сообщает о факте вывода кадра на экран. Ну сами посудите, в какой момент может освободиться блок в очереди? Именно тогда, когда в его содержимом уже нет нужды – кадр сформирован и «выдан». Вот это событие уже интересно, оно «как-то» коррелирует с тем, что изображено на экране монитора. Зная момент вывода кадра и номера текущей строки вывода (что легко получается из ScanLine) не составляет труда отследить положение и размер сегмента вывода на экран монитора. Здесь есть одна тонкость, но о ней чуть позже – не стоит смешивать разные проблемы.
Довольно любопытно, что «вход» в процедуру хоть и мало что значит, но представляет практически то же, что и «выход» из нее. Причина кроется в цикличности процесса рисования и мало меняющихся затратах времени процессора на формирование кадра. После «выхода» проходит почти постоянный интервал (время процессора), затем следует «вход» в обработчик «Present» и этот момент фиксируется FRAPS. Если «время процессора» не имеет резких изменений по длительности, то «выход» и «вход» будут показывать практически одно и то же, просто немного сдвинуты во времени один относительно другого.
Ну а если программа не старается выдержать «время процессора» постоянным? Тогда примерное равенство окажется нарушенным и логи будут содержать большую величину «шума», чем есть в действительности. Впрочем, стоит сразу вернуться к «действительности» - момент оценки времени кадра по «выходу» из обработчика не гарантирует полной тождественности освобождения блока очереди. Дело в том, что ‘какой-то’ кадр может быть закончен во время формирования последнего кадра. Тогда драйвер не будет ждать освобождения очереди, ведь одна из ячеек уже освободилась.
Т.е. если между «входом» и «выходом» затрачивается время на ожидание, то это означает, что именно в этот момент произошел вывод на экран. Если дополнительных потерь времени не последовало, то событие «выход» никакой полезной информации уже не несет – кадр был выведен за время формирования этого кадра. Чем выше скорость кадров, тем менее точную информацию можно получить.
Позвольте сделать пару выводов, они нам пригодятся:
- Место получения времени события «Present» оказывает влияние на представление потока кадров. Измерение на «входе» менее точное и потенциально более «шумное»;
- Нестабильность кадров зависит от их скорости поступления (частоты). Чем она выше, тем большую погрешность вносит механизм отождествления вывода на экран через освобождение блоков очереди кадров. Иначе говоря, чем выше скорость кадров, тем сильнее занижается разброс.
Я долго не мог понять, почему 20-50 к/с легко и довольно точно пересчитываются из логов FRAPS в изображение на экране монитора, а с 200-300 к/с начинается морока - результат в 1.3-1.5 лучше того, что происходит в действительности. Оказывается все просто, сигнал «Present» лишь условно синхронизирован с выводимой картинкой. Можно или выполнить несложный пересчет или игнорировать, ценность в корректном измерении скоростей выше 150 к/с весьма призрачна.
реклама
Кроме потока отсчетов о времени кадров хорошо бы получить хоть какую-нибудь осмысленную информацию от драйвера. Увы, ничего ценного выудить не удалось. Единственно, что декларировано в описании DirectX – оценка отброшенных кадров, но эти данные особого интереса не представляют. Отслеживание статистики по кадрам оказалось первым, что было реализовано и результат наблюдений – «пустышка». Если не переключать «на ходу» разрешение экрана, то максимальное количество «droop frames» никогда не превышало «2». При этом практически всегда в логах фигурирует число «0» и заметить что-либо отличное от нуля я смог лишь добавив в программу поиск максимума.
Драйвер не отбрасывает кадры, по крайней мере ATI/AMD. Если я правильно разбираюсь в хлебных крошках, то FRAPS не смотрит статистику по отброшенным кадрам, но это и не нужно, коль скоро их практически не бывает. Это значит, что данные FRAPS (все равно) соответствуют действительным. Вот только во всем этом действие мало смысла, коль скоро не учитывается соотношение длительности выводимых кадров на мониторе.
Теоретически, собственная программа может собирать больше информации, чем представляют логи FRAPS, но, в данном случае, есть сопутствующая беда – на добавление нормального вывода в программе требуется написать этот самый «нормальный вывод», на что уйдет много времени, а результат желательно получить «сейчас». Кроме того, мне действительно стало интересно, возможно ли вообще из лога FRAPS вытянуть хоть что-нибудь разумное. Для «издевательств» есть Fraps-Calc и реальный вывод на монитор, через «маркеры», можно попробовать найти разумные закономерности. Под «разумные» я понимаю логически правильные выводы, а не подгонку результатов
.
Затратив некоторые усилия я подобрал нечто, отдаленно напоминающее правильный результат, хотя иногда наблюдалось не слишком удачное соответствие с происходящем на экране. Например, при высокой скорости кадров и практически полном отсутствии нечетных кадров программа сообщала лишь о 50-70 процентном снижении производительности, хотя должно быть почти 100%.
Причина описана выше и она может быть скорректирована. Существовали и серьезные «проколы», когда программа сообщала о высоком качестве вывода, хотя на экране отсутствовала половина кадров. Но это отмечалось лишь пару раз, причем на скорости порядка 500 к/с. Увы, недостаток метода. Повторюсь - частично он может быть скомпенсирован, ведь средняя ошибка предсказания вывода на экран по сигналу «Present» пропорционально скорости кадров. После коррекции вполне возможно обеспечить точность 5-15% для скоростей кадров 30-120 к/с, причем эта погрешность будет затрагивать только прибавку к средней частоте кадров, которая считается достаточно точно.
В результате, ошибка вычисления «эквивалентной» скорости будет не столь уж и большой. Кроме описанных проблем, отмечались отдельные приложения, формирующие весьма специфический поток кадров, которые вносят повышенную меру несоответствия между логом и действием на экране. Подобное я наблюдал лишь в «откровенной синтетике», реальные игры более предсказуемы. Впрочем, все сказанное лишь мое скромное мнение и самое время добавить «IMHO».
В качестве тестовой программы используется Heaven 4.0 и его зависимости формирования кадров отследить совсем не трудно.
Heaven (DirectX 9)
На диаграмме кадров добавлены два графика:
- Зеленый – средняя частота кадров;
- Красный – (предполагаемая) частота кадров на экране монитора.
Кроме того, в разделе «Resume» добавилась (предполагаемая) усредненная частота кадров, видимая на экране монитора. Понятно, что все это чистый воды «шаманство», но оно используется для конкретного приложения, по отдельным точкам эти показания проверены и скоростной диапазон укладывается в «нормальные» рамки 30-120 к/с.
DitectX 11:
Сравним данные двух реализаций.
|
|
скорость кадров, к/с |
соседних отсчетов, % |
кадров по Vsync, к/с |
|
|
|
|
|
|
|
|
|
|
|
|
|
реклама
Все цифры рапортуют о лучшей картинке в DirectX 11. О том же говоря и фотографии, снятые ранее. Это все, финал, больше ничего сделать нельзя и следует мириться с «данным»?
Попытка улучшить качество изображения
Давайте попробуем «что-нибудь» сделать. Первое, что приходит на ум – включить вертикальную синхронизацию. При этом видеокарта сможет полноценно буферизировать вывод, что должно сгладить неодинаковость соседних кадров. Да и факт привязки к кадровому синхроимпульсу избавит изображение от разрыва объектов. В качестве испытательного объекта я возьму тест производительности игры Hard Reset.
Игра сделана с использованием DirectX 9 и, по отзывам, очень не дружественна к CrossFireX и SLI. Запускаться тест будет на сборке из двух видеокарт AMD Radeon HD 6970 и то, что игра «что-то не любит» нам только на руку. Цель – получить как можно более плавную картинку на экране монитора.
Обычный режим, вертикальная синхронизация отключена:
Поведение «красной» линии вызывает тоску. Средняя частота кадров 46.1, из них на мониторе окажется лишь 32.2, скучно.
Включим синхронизацию:
Что любопытно, средняя скорость кадров практически не изменилась, но ряд характеристик стал хуже. Можно ли сделать что-то еще? Панель управления Catalyst ничего путного не предоставляет, но есть замечательная программа RadeonPro, которая способна исправить это недоразумение. Воспользуемся дополнительными режимами управления синхронизации.
Динамическая синхронизация.
Действие основано на активном управлении режима синхронизации с кадровой разверткой монитора. Если игра обеспечивает скорость формирования кадров выше частоты развертки монитора, то вертикальная синхронизация включается. Если не сможет обеспечить, то синхронизация отключается.
Двойной Vsync.
В описании к программе информация представлена весьма запутано. Можно воспользоваться переводом Google, но помощь в этом весьма спорна.
Технология двойного Vsync как-то связана с удвоением количества синхронизирующих сигналов, что позволяет выполнять подстройку не только на частоте кадровой развертки, но и на частоте в два раза ниже ее. Программа RadeonPro может не только управлять режимом синхронизации, но и ограничивать минимальную длительность между сигналами конца рисования. Давайте воспользуется этим сервисом и дополнительно поставим предел на 60 и 120 к/с.
Двойной Vsync с ограничением скорости кадров на уровне 60 к/с.
Двойной Vsync с ограничением скорости кадров на уровне 120 к/с.
Страницы материала
Лента материалов раздела
Соблюдение Правил конференции строго обязательно!
Флуд, флейм и оффтоп преследуются по всей строгости закона!
Комментарии, содержащие оскорбления, нецензурные выражения (в т.ч. замаскированный мат), экстремистские высказывания, рекламу и спам, удаляются независимо от содержимого, а к их авторам могут применяться меры вплоть до запрета написания комментариев и, в случае написания комментария через социальные сети, жалобы в администрацию данной сети.


Комментарии Правила