Измерение производительности видеосистемы: теория (страница 2)
реклама
Взаимодействие между центральным и графическим процессором, буферизация
Вертикальная синхронизация
Способ взаимодействия видеокарты и монитора зависит от интерфейса. Как его реализовали в «железе», так и будет работать программа обслуживания. Ранее существовал лишь аналоговый способ передачи, в котором изображение состояло из строк, образовавших кадр.
Для информирования дисплея о начале/окончании генерировались два синхронизирующих сигнала – Vsync и Hsync (вертикальная и горизонтальная синхронизации). Эти сигналы использовались монитором для организации развертки изображения по строкам (Hsync) и кадрам (Vsync).
реклама
Принцип передачи основан на «рисовании» изображения лучом, который засвечивает точки на экране при проходе слева-направо по строке с последующим переходом к следующей строке в цикле до тех пор, пока не «пройдет» все точки (пикселы) от верха экрана до самого низа. Черными линиями отмечен обратный ход луча, который необходим для перемещения точки свечения с конца предыдущей строки в начало следующей, при этом сам луч гасится в обязательном порядке.
Сигналы синхронизации не являются догмами, монитор лишь выполняет по ним синхронизацию (поэтому всегда говорят о «синхросигналах») и при кратковременном отсутствии кого-либо из них, либо выходе за допустимые пределы, дисплей начинает их собственную генерацию внутри себя. Обычно монитор при этом гаснет и на экране появляется сообщение о недопустимом режиме работы. В связи с особенностью реализации развертки на отклоняющейся системе, длительность обратного хода луча по строкам и кадрам не может быть слишком маленькой. Увы, во время обратного хода информация на дисплей не передается, что означает простаивание интерфейса в эти моменты времени.
Переход на «цифровые» интерфейсы изменил лишь внешний вид кабелей, оставив ту же философию обмена – данные кадра передаются построчно, от первой до последней строки с формированием Vsync в конце. Компания Intel начала активно продвигать альтернативный вариант передачи видеоинформации, при котором по интерфейсу будет передаваться только та часть изображения, которая подверглась изменению, что позволит снизить весьма высокие требования по скоростным характеристикам интерфейса (ведь уже сейчас требуется отправлять «единицы гигабайт» данных в секунду) и повысить скорость обновления изображения.
Правда, особо значительных дивидендов ждать не приходится – при модификации изображения всего экрана, что свойственно фильмам и играм, в любом случае потребуется полное обновление. Сюда же стоит добавить новые проблемы с «плавающей» частотой развертки, ведь игры считают скорость вывода на монитор постоянной.
Впрочем, это вопрос далекого будущего, в ближайшее время способ передачи информации останется прежним – построчно, с первой до последней. Видеокарты проектируются под этот формат, а потому их взаимодействие с монитором основано на синхросигналах по строкам и кадрам. По теме данной статьи интерес представляет сигнал вертикальной синхронизации (Vsync), по которому видеокарта осуществляет смену кадров.
Вывод на монитор, буферизация
Для обеспечения вывода графической информации в видеокарте определяется блок памяти, в котором формируется кадр для передачи на монитор. При начале вывода, иначе говоря, при начале передачи первой строки, устанавливается начальный адрес в этом блоке и по мере «движения» вдоль строки осуществляется считывание некоторого количества байт по текущему адресу с отправлением уровней цветов R-G-B (красный-зеленый-синий) по интерфейсу в монитор, после чего адрес увеличивается и цикл вывода повторяется. После окончания строки формируется сигнал горизонтальной (строчной) синхронизации и устройство переходит к следующей строке.
Таким образом происходит последовательное считывание картинки в блоке памяти видеокарты с передачей ее в монитор. По окончании вывода последней строки формируется сигнал вертикальной (кадровой) синхронизации и весь процесс повторяется заново. С точки зрения видеокарты, работа с дисплеем состоит в циклическом считывании блока памяти с передачей данных через внешний интерфейс. Во время обмена данные трансформируются каким-либо образом, в зависимости от типа интерфейса, но для логики работы устройства это не представляется сколь-нибудь важным.
реклама
Что же это за блок памяти? Некоторый регион в локальной памяти видеокарты, в котором сформирован выходной кадр. Если устройство вывода использует «оконный» режим работы (windowed), то этот блок является статичным и при выводе разных программ на экран происходит изменение состояния отдельных ячеек именно в нем. Характерная особенность – если изменение изображения не попадает на время Vsync, то появляются соответствующие дефекты.
Эффект разрыва изображения окна при перетаскивании может быть вызван не только долгим формированием изображения (довольно слабой) видеокартой, но и любыми другими факторами, привязанными к вертикальной синхронизации – вывод разных кадров, буферизация в мониторе и прочие. По этой причине дефект может проявляться более или менее заметно, вплоть до едва различимого.
При работе видеокарты «в окне» часто используется буферизация графических построений в системную память, вместо обязательного использования локальной памяти ускорителя. После построения кадра программа вызывает функцию быстрого копирования в видеопамять. На первый взгляд, системная память не так производительна, как установленная на современных видеокартах, и подобная буферизация должна приводить к падению производительности, но не все столь прямолинейно. Да, системная память медленнее локальной памяти видеокарты, но она находится «ближе» к процессору.
Локальная память видеокарты адресуется в пространство PCI и так же может «просто» читаться и записываться, как и системная память, вот только команды будут проходить через PCI (Express) интерфейс, что вызовет очень большие задержки. Плюс к тому, в процессоре под разные регионы его адресного пространства указываются собственные режимы кэширования. Под обычную память используются установки максимальной производительности, а на регион PCI требуется максимальная совместимость и все кэширование отключается. Кэширование доступа можно использовать в системной памяти из-за того факта, что заранее известна ее особенность – то, что было записано в ячейку, то оттуда же и считается.
Для периферийных устройств это тождество исполняется далеко не всегда, существуют ячейки (адреса) «только на чтение» и «только на запись», либо более сложные комбинации признаков. Если на такую ячейку назначить кэширование, то работа периферийного устройства станет невозможной. А потому, из условий совместимости, на регион PCI кэширование не распространяется. Довольно давно занимался вопросом тестирования видеопамяти, использовал метод прямого доступа. При назначении кэширования скорость тестирования возрастала в несколько раз и становилась соизмерима со временем доступа к системной памяти. Ранее похожая функция реализовывалась через настройку «Fast write».
Если посмотреть скорость работы аналогичных программ (VideoCardStabilityTest, memtestCL, vmt), то создается впечатление, что ничего нового в этом вопросе не произошло, кэширование так и не включили. Впрочем, на скорости работы видеокарты это никак не сказывается – она выполняет операции со своей локальной памятью и особенности доступа со стороны процессора не затрагивают ее функционирование.
При смене типа на «полный экран» (Full screen) идеология работы с буфером кадров меняется. В таком режиме происходит изменение всего кадра, а потому появляется возможность не собирать выводимое изображение из кусочков, а формировать весь кадр заново, причем кадров может быть несколько. Обычно, если видеокарта и монитор переходят в режим «полный экран», то это делается для какого-то одного приложения, а значит и вывод картинки будет формироваться только им. Такое монопольное использование позволяет применить более гибкую буферизацию вывода – строить изображение в дополнительном буфере и лишь по готовности копировать в буфер вывода на экран.
Процесс формирования трехмерного изображения является многостадийным процессом, причем только по завершении всех операций изображение получается в правильном виде. Поэтому попытка строить картинку прямо в блоке вывода обречена на провал – на экране будет что угодно, только не изображение. Это означает, что создавать изображение следует в «другом» блоке, который позже следует скопировать в блок вывода, и он будет выводиться... пока будет генерироваться следующий кадр. Вот так мы и пришли к технологии «заднего» (или «теневого») буфера (backbuffer).
Данная модель создает картинку трех цифр (слева), по синхроимпульсу копирует кадр в выходной буфер (в середине) и выдает изображение на экран (справа). Принцип взаимодействия прост – пока на монитор выводится предыдущий кадр, программа должна успеть построить следующий. Но операционная система типа Windows (к слову, как и Linux) не является системой реального времени, а потому может занять процессор своими собственными нуждами.
Если последует подобное воздействие (а оно «типично»), то программа не успеет построить кадр за отведенное время и возникнет «прокол» – пришло время копирования в блок вывода, а новый кадр еще не построен.
В этой модели построение «голубого» кадра немного задержалось, при этом скорость формирования осталась прежней.
Видеокарта не может переписать только часть нового кадра, ведь неизвестна стадия, да и «построчно» никто не будет устанавливать признаки готовности. В результате, будет обнаружен конфликт (отсутствие нового кадра), и по нему можно выполнить не так уж и много действий – видеокарте остается лишь продолжить вывод того кадра, что был представлен ранее. Иначе говоря, наступление Vsync означает необходимость копирования из «заднего» блока на блок вывода. Как можно противодействовать вмешательству операционной системы или дополнительных задержек в исполнительном конвейере графического процессора?
реклама
Например, сделать не один, а два задних буфера. Вначале заполняется один, затем второй. Если возникнет задержка, то это не вызовет конфликта, поскольку между блоком вывода и блоком формирования изображения расположен еще один блок, из которого и будет браться кадр вывода. Кроме защиты от задержек, наличие двух «задних» блоков позволяет формировать картинку, не заботясь о жесткой синхронности к Vsync.
После переноса вычислительной деятельности по работе с изображением с центрального процессора на графический идеология взаимодействия CPU-VGA претерпела кардинальные изменения, но работа переднего и задних буферов осталась прежней. Вывод на монитор осуществляется из переднего буфера, построение в задних буферах. Переход к многопроцессорной обработке требует передачи результирующих кадров из «подчиненных» к «основной» видеокарте, что выполняется через дополнительные «мостики».
Но сложности заключаются не в способе передачи, а во времени, необходимом на выполнение этого процесса. Множественная буферизация построения кадра, используемая в одной видеокарте, служит целям этой видеокарты, и возлагать на буфера функцию кэширования SLI/CF кадров было бы неверно – тем самым можно легко снизить качество их работы. Поэтому объединение кадров с разных видеоплат хорошо бы выполнять в отдельном, специальном буфере, который не затрагивает систему буферизации ведущей видеокарты. В принципе, так оно и выполняется – при работе в SLI/CF задержка формирования изображения увеличивается на длительность одного синхроимпульса (дополнительная буферизация).
Pre-Rendered Limit
Центральный процессор работает совместно с графическим процессором видеокарты. Первый формирует описание и выполняемые действия, второй это исполняет. Средство взаимодействия между ними выполняется через графическую прослойку какого-либо API, зачастую заканчивающегося в Gdi32, и персонального драйвера видеокарты.
Индивидуальность заключается в том, что драйвер под свои видеокарты производят фирмы-разработчики графических процессоров. А вот графические API – это уже стандартные (и не совсем) функции операционных систем. Но неважно, не стоит залезать в проблему глубже, чем это необходимо, бритва Оккама.
Метод взаимодействия процессора с API D3D состоит в циклическом процессе формирования информации о кадре, передачи данных и выдачи команды Present (для Direct3D), которая сообщает о том, что посылка сформирована. После этого цикл повторится снова, и так будет выполняться для каждого кадра. Если отлавливать вызов Present, то можно легко получить признак наличия кадра. Будет ли он соответствовать тому, что выводится на монитор? Совершенно необязательно.
Сформированное описание кадра может не сразу отправляться на расчет, а лишь откладываться в накопительный буфер с последующей передачей на выполнение. Глубина буфера задается в самих прикладных программах (обычно на этапе создания устройства), но может быть навязана через управление драйвером видеокарты. Для NVIDIA в настройках D3D существует параметр «pre-rendered frame limit», задающий длину буфера (очереди), то есть количество кадров, которые может создать программа до того, как будет обработана видеокартой. Формулировка NVIDIA звучит следующим образом:
Maximum pre-rendered frames limits the number of frames the CPU can prepare before the frames are processed by the GPU. In creasing this value can result in smoother gameplay at lower framerates. Reduce this value if you experience a delay in response to input devices such as a mouse, gamepad, or keyboard while playing games.
This feature only works for games using DirectX.
Введение буфера порождает проблемы и увеличивает задержку вывода, но без него следует значительное падение производительности из-за неизбежных стадий ожидания готовности устройств, процессор будет постоянно ждать видеокарту (что нормально), а видеокарта – процессор (а вот это уже плохо). Обычное значение количества буфера составляет три кадра, в настройках контрольной панели драйвера NVIDIA версии 3хх его можно менять от 1 до 4, но сами программы отличаются несравнимо большими возможностями.
Положительный эффект от дополнительных буферов проявляется в том, что процессор может загружать данные в видеокарту даже тогда, когда она занята расчетами ранее представленной информацией. С другой стороны, физический процессор не может монопольно использоваться какой-нибудь одной программой – Windows многозадачная среда и количество исполнительных ядер в ЦП всегда меньше активных потоков.
Как следствие, программа не всегда может выполняться, существуют паузы. При наступлении временных пропусков видеокарта может забирать кадры из буфера, поэтому падения производительности не произойдет. Иначе говоря, чем больше размер буфера загрузки, тем более продолжительные «провалы» может перенести система без нарушения качества предоставления визуальной картинки. С другой стороны, при частоте развертки монитора 60 Гц каждый шаг буферизации отнимает 16.7 мс. Это может быть и пустяк, только не забудьте учесть задержки на двойное-тройное буферизирование в видеодрайвере.
Впрочем, «pre-rendered» на 8 кадров (8*16.7=133 мс) вы почувствуете сразу, это примерно 1/7 секунды. Подобное вряд ли случится в реальных играх, но разве не было такого, что счетчик FPS показывает весьма приличные значения, но мышка «тормозит» так, что целиться невозможно? Повышенная задержка может быть вызвана неудачным (редким) вызовом процедуры обсчета сцены, а может быть и излишне «оптимистическим» отношением к объему буфера. Хотя обычно программы не переназначают «типичное» значение и используется кэширование на 3 кадра. У AMD существует аналогичная настройка, «Flip Queue Size», вот только она убрана из настроек драйвера и, как показала моя проверка, не работает. Не больно-то и хотелось.
Всегда ли присутствует вред от кэширования входной информации? Вообще-то, взаимодействие системы напоминает классическую задачу с бассейном и двумя трубами, где «трубами» являются процессор и видеокарта, а количество воды в бассейне – мера использования буфера (и привносимая им задержка). Если процессор заливает быстрее, чем может видеокарта, то бассейн (буфер) заполнится до краев и система стабилизируется. Если же лучшие скоростные качества окажутся у видеокарты, то вода не успеет собраться вовсе, все сразу вытечет.
Увы, второй сценарий встречается крайне редко, мощности любого современного процессора (как правило) более, чем достаточно. Хотя бывают исключения, например, все тот же неувядающий S.T.A.L.K.E.R. и игры на его основе (Metro 2033). В данном случае в основной «графический» поток процессора помещена не только работа с видеокартой, но и какая-то сторонняя активная деятельность, приводящая к сильной загрузке ЦП. Для этого случая большой буфер мог бы и помочь, только задержки в игре могут составлять единицы секунд, что никаким кэшированием не исправить.
Итак, вступительная часть закончилась, переходим к сути статьи.
Проблемы качества изображения
Графический процессор должен обеспечивать формирование не менее одного кадра до момента получения сигнала Vsync, по которому это изображение будет перемещаться в буфер вывода и транслироваться на монитор. В случае одиночной видеокарты все просто – обеспечили данную скорость поставки – пропуска кадров не будет. Не успели – прокол, повторится предыдущий кадр. Если же используется многопроцессорная обработка, с типичным для нее эффектом нарушения фазности, то какой может быть картина? Разберемся.
Вариант номер 1 – «да все равно»
Когда говорят о дефектности работы SLI/CF, то часто приводят примерно такие картинки:
Название видеокарты и игры указано в верхней строчке картинки. Теперь CrossFireX редакция:
Жуть, да и только. Посмотрим поближе:
Проблемы с фазой между GPU, уже было.
Как было показано ранее, для того, чтобы сформировать кадр, видеокарта должна создать его в заднем буфере (back buffer) в любое время, но до наступления события Vsync, ибо по нему произойдет копирование из заднего буфера в передний и вывод на монитор. А посему, какая разница, в какой именно момент пришел новый кадр, если он успел (или не_успел) прийти до требуемого отсчета? Напоминаю, в видеокарте применяется множественное кэширование вывода.
Второй аргумент – частоту развертки 60 (120) Гц глаз не видит, «что-то» заметное начинается только с 30 Гц. Сделаем простое действие – система кэширования обладает «силой», как минимум, на один отсчет, значит нестабильность соседних отсчетов можно не учитывать. Дабы не рушить логику работы программы и данные лога, их можно просто усреднить. После этого график станет выглядеть следующим образом:
Посмотрите на график одиночной карты (HD 6970). Вот теперь можно сыграть в игру «найди два отличия». Первое – скорость возросла с 67 до 118 FPS (+77%), второе... вот и все, других отличий нет.
Crysis – это только одна игра, может на других этот эффект не повторится? Проверим на примере Arcania.
Вариант CrossFireX:
После усреднения соседних кадров:
Вообще-то, отличия есть. Если в Crysis 2 блокировка разброса соседних отсчетов приводила картинку к виду одиночной карты, то здесь наблюдаются весьма сильные «вспышки». Интересно, что повышенная нестабильность связана с низкой эффективностью работы CrossFireX и переход от одного к двум GPU привел к увеличению всего лишь на 20% (62.6 и 74.9 FPS). Это подтверждает предположение, что падение эффективности SLI/CF «бесплатным» не бывает – растет «дефектность».
реклама
Страницы материала
Лента материалов раздела
Соблюдение Правил конференции строго обязательно!
Флуд, флейм и оффтоп преследуются по всей строгости закона!
Комментарии, содержащие оскорбления, нецензурные выражения (в т.ч. замаскированный мат), экстремистские высказывания, рекламу и спам, удаляются независимо от содержимого, а к их авторам могут применяться меры вплоть до запрета написания комментариев и, в случае написания комментария через социальные сети, жалобы в администрацию данной сети.
Комментарии Правила