Измерение производительности видеокарты оценивают количеством кадров в единицу времени, которое она способна сформировать. Чем их больше, тем выше плавность изображения. Вроде все логично и бесспорно, так откуда же возникают сомнения?
Впрочем, я несколько увлекся, пока что никаких проблем нет – чем выше FPS, тем лучше работает графическая система! Теперь возьмемся за «варианты».
Замерить производительность довольно просто – достаточно воспользоваться одной из программ, которые обеспечивают вывод количества кадров в секунду. Ранее существовали лишь FRAPS, D3DGear и некоторые другие, впоследствии парк средств значительно расширился... но суть их работы примерно одинакова и, в достаточной мере, повторяет смысл функционирования FRAPS, поэтому стоит ограничиться только этой программой, имея в виду и все другие.
Комплект FRAPS состоит из модуля «fraps.exe», который является основной исполнительной программой, и нескольких библиотек «fraps**.dll». Смысл последних – прицепляться к запущенным процессам для получения доступа к функциям графического вывода. Эти библиотеки перехватывают выполнение некоторых команд API OpenGL/DirectDraw/Didect3D.
Кроме перехвата, в процессе своей деятельности они активно вызывают другие графические функции, например, при выводе текста и примитивов на экран. Как следствие, любая программа типа FRAPS неизбежно внесет дополнительную нагрузку на процессор/видеокарту и создаст искажения в получаемых результатах. Впрочем, эпоха «Riva TnT» давно канула в лету, поэтому особо сильного влияния ждать не приходится.
Программы показывают в окне игры скорость кадров, которые вычисляются по получению команды «Present», сообщающей об окончании формирования каждого кадра со стороны программы. По идее, последующие стадии формирования и обработки изображения в графическом процессоре не должны (бы) вносить никаких изменений – сколько кадров сформировано программой, столько их и должно (бы) быть выведено на монитор. Но не все так просто, и все становится «совсем не просто» при переходе к многопроцессорной обработке.
Для анализа данных можно импортировать логи FRAPS в программу Excel с последующей обработкой, вот только продукция Microsoft отличается своей «тормознутостью» и ее применение приравнивается к каторге. Пришлось сделать свое, что-то более производительное. Данная статья вовсе не о Fraps-Calc, но я постоянно буду на нее ссылаться, поэтому некоторые пояснения необходимы.
Программа формирует несколько графических представлений исходных данных и выполняет простейшую обработку.
В средней части размещаются результаты анализа по отдельным типам.
Раздел «Statistic»:
Раздел «Stable FPS» содержит таблицу подсчета стабильности построения кадров по критерию времени периода. Фактически, выходит спектр устойчивости получаемого потока кадров. Левый столбец означает относительную устойчивость по входным данным лога, «правый» повторяет «левый», но выполняет нормирование к образцовой частоте кадров 60 к/с. Последнее нужно для объективного сравнения результатов видеокарт с различной производительностью.
Раздел «Freeze» определяет наличие «остановок» и минимальную/максимальную скорость потока кадров из анализа спектра. Использование фильтрации «шума» при построении спектра позволяет исключить случайные «проколы», что улучшает определение минимальных и максимальных значений. На этом и завершим экскурс по программе.
Так уж выходит, что скорости видеокарты всегда оказывается недостаточно – современные игры всегда оптимизируют на самые производительные решения, ведь качество картинки напрямую зависит от сложности выполняемых действий. Сюда же стоит добавить извечное желание использовать монитор высокого разрешения, что повышает нагрузку на видеокарту еще больше и это напрямую востребует переход на качественно другой уровень,... а именно – многопроцессорную обработку.
Название технологий у фирм NVIDIA и ATI, извините, AMD, различается – «SLI» и «CrossFireX», но суть остается схожей – вместо одной-единственной видеокарты устанавливается несколько штук (чаще две), которые работают совместно. Здесь применяется способ поочередного расчета, когда четные кадры обрабатывает одна видеокарта, а нечетные другая. Коль скоро в сборках используются две одинаковые модели, то и расхождений в работе быть не должно (бы).
В идеале, производительность системы должна повышаться прямо пропорционально количеству графических процессоров. Но, увы, переход от одного графического ускорителя к двум не увеличивает количество кадров в два раза, что прямо говорит о наличии внутренних проблем. Вопрос «скорости» выходит за рамки данной статьи, хочется лишь отметить, что когда в системе есть какие-то незапланированные потери, то это всегда приводит к нестабильной работе (универсальное правило). Применительно к видеокартам это означает, что следует ожидать странностей с качеством картинки.
Режим работы с разделением выполняемого потока на два графических процессора с поочередным формированием кадров является самым популярным – при нем требуется минимум дополнительных затрат, надо лишь перераспределять запросы обслуживания из общего потока на два устройства. Обе видеокарты работают одновременно и независимо, получаемая картинка передается через мостики, устанавливаемые между платами. Существует способ передачи информации без дополнительных аксессуаров, через шину PCI -Express, но этот прием увеличивает задержки и дополнительно загружает шину PCI-Express, которая и так весьма интенсивно используется для управления и передачи данных к видеокарте, а потому в производительных решениях не применяется.
Описанное построение многопроцессорной обработки является простым и надежным, проблемам взяться (бы) неоткуда, но они есть. Никто не будет специально разрабатывать технологии обработки изображения, применительно к многопроцессорным системам – все так и продолжает использоваться с ориентированием на одиночную видеокарту. Отчасти это правильно, ведь выпуск сдвоенных видеокарт или «попарная» сборка у пользователя составляют лишь малый процент от общего выпуска видеоускорителей, а потому серьезные вложения в данный вопрос не окупятся. С другой стороны, пользователи уже устали от постоянных «глюков» с SLI/CF и фирмы-разработчики «хоть что-то» делают в этом направлении.
Итак, совместная работа двух видеокарт (точнее двух GPU, в пределах платы количество графических процессоров может быть больше одного) базируется на работе двух независимых видеокарт, каждая из которых участвует в формировании картинки, только одна из них обрабатывает четные кадры, а другая – нечетные. Все логично, но где же подвох? Какой смысл постоянно повторять одно и то же, если оно очевидно? Увы, нет, смотрите сами – каждая видеокарта является независимым исполнительным устройством, в которую (уж извините за избитое сравнение с «бассейном») в одну трубу вливается «задание» от драйвера (через PCI-Express), а из другой (мостик между платами) выливается полученный кадр. Сложность современных игр, а ведь именно для них чаще всего и используются 3D-ускорители, всегда опережает возможности этих устройств, что означает их полную «занятость», видеокарты никогда не простаивают.
При сильном утрировании графический ускоритель можно представить в виде мотора, который крутит диск. Чем быстрее мотор (производительность 3D-ускорителя) и легче диск (сложность картинки), тем быстрее оборот диска (время обработки). При этом кадр считается сформированным только после полного оборота (выполнены все фазы обработки картинки). Теперь берем второй «мотор» и запускаем его рядом. Диски будут крутиться с той же скоростью и общее количество оборотов повысится в два раза. Положим, что подаваемая «мощность» моторов и другие характеристики одинаковы. Пока логично, ничего не забыли? Забыли, фазу. Даже при полностью одинаковых условиях работы и, как следствие, скорости, «фаза» вращения двух дисков не обязательно будет одинаковой.
Рассмотрим два случая. Вариант с удачным соотношением фаз:
Расстояние (то есть время) между построенными кадрами одинаково. В случае расхождения фаз картинка несколько изменится:
Теперь расстояние между соседними кадрами не одинаково, хотя производительность обеих видеокарт не изменилась.
Если же отойти от полнейшей абстракции к реальным построениям, то «фаза» получения выходных кадров будет не только «случайной», но и постоянно «меняться». Не бывает одинаковых кадров, один чуть сложнее другого (сменился ракурс, чуть большая зона видимости) и фазовое расхождение будет меняться.
Рассмотрим два случая, оба на «парной» видеокарте AMD Radeon HD 6990 (с двумя графическими процессорами). В качестве иллюстративного материала будут использоваться собственные логи и информация, любезно представленная в статье «AMD CrossFireX под микроскопом. На примере Club3D HD 6990». При возникновении вопросов по полученным данным рекомендуется изучить приведенный цикл статей. Хотя их будет интересно почитать и «просто так».
Возвращаемся к нашим проблемам, игра F1:
Вполне адекватный график, теперь несколько иной ракурс:
Игра та же, как и схожие условия тестирования, но внешний вид претерпел существенные изменения. Взглянем поближе:
Налицо кадры разной продолжительности. В получаемом спектре прослеживаются две четкие составляющие 75 и 150 к/с, и напрашивается вывод о разной производительности видеокарт, ведь время формирования кадра отличается почти в два раза. Кстати, подобная «чехарда» охватывает лишь соседние отсчеты или затрагивает и более продолжительное время? Попробуем сконвертировать данные таким образом, что будет эмулироваться поток одиночной видеокарты – просто усреднив время построения соседних кадров. Получится следующее:
А что, весьма неплохой график. Отсюда вывод – «шум» на графиках вызван работой многопроцессорной графической системы. Предположение об изменении производительности одной из видеокарт оказалось ложным, и вот почему – программа сбора статистики (лог снимался с помощью FRAPS) получает данные в точке передачи заданий на исполнение в API Direct3D и ничего не подозревает о каких-либо «особенностях» реализации системы. При работе видеокарты HD 6990 (с двумя графическими процессорами) поток исполнения разделяется пополам – для первого и второго устройства, каждое из которых обсчитывает свои кадры.
Ранее я приводил сравнение с двумя моторами и здесь именно такой случай: оба GPU формируют кадры, причем с одинаковой производительностью, вот только фаза одного немного сдвинута относительно другого. Если бы они работали синхронно и со сдвигом фазы в 180 градусов (половина оборота), то выходные кадры формировались строго с одним и тем же периодом.
Такое возможно, посмотрите на первую картинку с более стабильным графиком. На второй картинке между исполнительными устройствами возник дополнительный фазовый сдвиг, что привело к неодинаковому интервалу в получаемых кадрах. Посмотрите на крупный план второй картинки, фазовый сдвиг меняется (нижние и верхние части графика отдаляются больше и меньше). Скорее всего, это зависит как от межкадровой разности, так и от общей сложности выполняемых действий. Подобный вид «расслоения» порождается отсутствием синхронизации между исполнительными устройствами и является типичным.
Является ли это «дефектом» и стоит ли на него обращать внимание – вот с этим и необходимо разобраться.
Вертикальная синхронизация
Способ взаимодействия видеокарты и монитора зависит от интерфейса. Как его реализовали в «железе», так и будет работать программа обслуживания. Ранее существовал лишь аналоговый способ передачи, в котором изображение состояло из строк, образовавших кадр.
Для информирования дисплея о начале/окончании генерировались два синхронизирующих сигнала – 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 задержка формирования изображения увеличивается на длительность одного синхроимпульса (дополнительная буферизация).
Центральный процессор работает совместно с графическим процессором видеокарты. Первый формирует описание и выполняемые действия, второй это исполняет. Средство взаимодействия между ними выполняется через графическую прослойку какого-либо 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 «бесплатным» не бывает – растет «дефектность».
Остается лишь один вопрос – повышенный разброс кадров, причем точно не в соседних отсчетах, связан именно с работой CrossFireX или же здесь присутствуют какие-то сторонние факторы? Для чистоты эксперимента возьмем видеокарту другого производителя:
Графический ускоритель другой, производитель другой, производительность схожая, как и дефекты. На одиночной видеокарте наблюдаются те же «вспышки» нестабильности, причем в тех же местах. Нет, технология CrossFireX в их появлении не виновата, коль скоро дефект проявляется и на одиночной видеокарте.
Battlefield: Bad Company 2. Одиночная видеокарта:
Сдвоенная:
Усредняем соседние отсчеты:
Эффективность CrossFireX 68% (63.6 против 107.1 FPS), каких-то особенных дефектов не наблюдается. На графиках присутствуют периодические «всплески», но они есть и на одиночной, и на сдвоенной видеокарте.
Dirt 2. Одиночная карта:
Сдвоенная:
После фильтрации:
Эффективность CrossFireX 68% (61.9 против 104.2 FPS). Интересно, увеличение скорости работы аналогично предыдущей игре, но здесь наблюдается повышенная дефектность. Воспользуемся «противоположным» решением:
М-да. Даже на одиночной карте, причем совсем другой, эта игра по-прежнему демонстрирует свою «нестандартность» – ну вы сами видите, комментарии излишни.
Dragon Age 2. Одиночная карта:
Сдвоенная:
После фильтрации:
Эффективность CrossFireX 52% (64.6 против 98.1 FPS).
Mafia 2. Одиночная карта:
Сдвоенная:
После фильтрации:
Эффективность CrossFireX 23% (71.9 против 88.4 FPS).
Shogun 2. Одиночная видеокарта:
Сдвоенная:
После фильтрации:
Эффективность CrossFireX 13% (61.7 против 69.7 FPS).
S.T.A.L.K.E.R.. Одиночная видеокарта:
Сдвоенная:
После фильтрации:
Эффективность CrossFireX 38% (69.9 против 96.2 FPS). У одиночной видеокарты в левой части графика наблюдается некоторый «разлет», аналогичный дефект присутствует и на сдвоенной (после фильтрации).
Короче говоря, переход на CrossFireX не порождает дополнительных проблем с качеством изображения. Повышенная нестабильность соседних отсчетов подавляется дополнительной стадией буферизации. Что до самих игр, то переход на многопроцессорную обработку не привносит дополнительных дефектов, по крайней мере, явных.
Если с этим вопросом разночтений нет, то переходим к следующему.
Вариант номер 2 – «еще как влияет!»
Убедив в одном, давайте попробую убедить в прямо противоположном.
После всех стадий обработки и буферизации (кэширования) поток кадров попадает в последний буфер вывода и оттуда выводится на монитор. Пожалуйста, ответьте на простой вопрос – вы играете в игры с включенной синхронизацией? Утвердительно на этот вопрос ответят единицы, да и то, с оговорками. «Вредоносное» свойство жесткой кадровой синхронизации очевидно, к слову, как и тот вред изображению, которого она позволяет избежать. Но при раскладе «сильный провал производительности» против «дефекты изображения» для большинства пользователей выбор очевиден.
Что же происходит во взаимодействии «игра-драйвер-видеокарта» при частоте кадров выше частоты импульсов кадровой развертки? Небольшое время буфер «pre-rendered» может поглощать излишние кадры, но его емкость мала и быстро произойдет насыщение. Все остальные буферы в видеокарте небольшие и не способны выполнить сколь-нибудь существенную функцию буферизации избыточных кадров.
В результате, у цепочки «Direct3D»-....-«выход на монитор» остается только два варианта, или выкидывать кадр, или «насаждать», переустанавливать картинку прямо в буфере вывода. Последнее означает гарантированное повреждение целостности картинки. Например, нечто такое:
На картинке четко видно наложение двух кадров, примерно по середине. А именно – вначале выводится первый кадр, потом он был вытеснен на другой и вторая половина содержит уже второй кадр. Человеческий глаз не заметит мерцания и прочих дефектов с частотой 30-60 Гц, но появление чего-то нового или искажение линейных форм будет замечено сразу. Впрочем, вопросы эстетики и борьбы с этим недугом выходят за рамки данной статьи, позвольте лишь отметить очевидное – выключение кадровой синхронизации приводит к неприятным дефектам.
Впрочем, выключенная синхронизация может улучшать качество картинки. Отключение Vsync приводит к разрыву изображения, особенно при интенсивном движении. Но бывают ситуации, когда качество изображения становится лучше. Парадокс? Увы. Режим построения основан на покадровом расчете, при этом каждый кадр считается четко и в фокусе. Это хорошо для просмотра, но не слишком подходит для движения. Мозг привык воспринимать движущиеся объекты смазанными, это нормально, вот только в 3D сценах все всегда четко.
Скажете «глупости»? Простой пример – вы сидите в вагоне, который движется в тоннеле. При этом каждый кадр будет показывать мгновенный «снимок экрана» движения. Но что будет пониматься от такого движения? Дерганье, при любом FPS.
Включение кадровой синхронизации ничего не улучшит, ведь источником проблемы является высокая четкость каждого кадра. Здесь помогло бы «размазывание», только это может быть реализовано лишь средствами игры, видеокарта по собственной инициативе не способна исправить данный дефект. Если отключить кадровую синхронизацию и обеспечить заведомо высокую скорость потока кадров, значительно выше частоты кадровой развертки монитора, то на экране наступит «хаос» из налагающихся кадров, что снизит «дискретность» отдельных кадров. Впрочем, я отвлекся, извините.
При приходе избыточного кадра и включенной синхронизации, вызывающий поток останавливается до освобождения буфера. Фактически – до прихода Vsync. Если не происходит задержек в операционной системе, то следует простой цикл: поток игры выдает «Present», который сообщает о сформированности кадра, функция API Direct3D этот вызов принимает и не возвращает управление до тех пор, пока кадр не обработается. Причем не обязательно именно тот, который только что запросили – главное, освободить блок буферизации. После возврата из функции поток делает «свои дела», формирует задание по новому кадру и снова выдает Present... и этот цикл повторяется.
В случае существенной задержки операционной системы при поступлении «Present» API Direct3D не ждет и практически сразу возвращает управление, ведь за время вынужденного простоя одна ячейка буферизации освободилась. Вот так и появляются «шипы» (всплески) потоков программ мониторинга типа FRAPS. Типичный пример:
В начале графика длительность кадра соответствует интервалу Vsync, после которого следует один очень долгий интервал и один короткий. Скорее всего, повышенная длительность вызвана незапланированными задержками и за это время явно был пропущен Vsync. Таким образом, простейшие анализаторы лога покажут два события: пропущенный кадр и короткий кадр. Но это не соответствует действительности – полезную информацию несет лишь долгий кадр, но он не вызывает пропуска, о котором могут сообщать анализаторы, он лишь говорит, что была задержка обмена. При этом сама видеокарта работала в нормальном режиме и обсчитывала те кадры, которые были положены ранее (по умолчанию, 3 кадра).
И «тем более» понятно наличие «короткого» кадра сразу после «долгого» – в освободившуюся ячейку данные кладутся сразу, не дожидаясь освобождения, ведь она уже свободна. Вполне очевидно, что «дерганность» есть только в логах, в действительности ее нет. До тех пор, пока хватает «силы» системы кэширования в видеокарте, никаких дефектов нет, ускоритель работает без остановок. К слову, примерно так выглядит лог при спонтанной нагрузке операционной системы:
Первая строка показывает общее количество кадров в секунду, остальные позиции – отличие их длительности от номинальной. При незапланированной нагрузке всегда следует пара событий – один короткий и один длинный. Если посмотреть количество кадров на интервал Vsync, то вначале следует «длинный» (то есть пропуск кадра) и короткий плюс нормальный. В результате на второй интервал приходится два кадра. Все правильно, пропуском кадра видеокарта истратила внутренний резерв и на следующем его восполнила.
Для нормальной работы видеокарта должна формировать один кадр на каждый Vsync. Отключение синхронизации это требование отменяет, теперь надо сформировать «не менее одного» кадра на тот же интервал времени. Во всех остальных случаях будет пропуск кадра, что воспринимается пользователем не слишком хорошо. Одна видеокарта может поставлять кадры с интервалом времени «T» (положим), две видеокарты со схожей производительностью (положим еще раз) также могут поставлять кадры с интервалом времени «Т», каждая. Во втором случае, в режиме SLI/CF мы будем получать кадры с интервалом времени «Т/2»?
Как бы не так! При работе парами (SLI/CF) видеокарты могут работать эффективно, но обладать фазовым сдвигом. Ранее было представлено множество картинок – фазовый сдвиг вовсе не постоянный и может меняться произвольным образом. Как следствие, время прихода кадров будет составлять не «Т/2», а находиться в интервале от «Т/2» (удачная фаза, сдвиг 180 градусов) до «Т» (неудачная, обе видеокарты работают «одновременно»). Переход на SLI/CF означает, что будет использоваться дополнительный буфер, который сгладит скачки между соседними кадрами, но только в том случае, если используется кадровая синхронизация. В ином случае это лишь дополнительная задержка.
В моменты нестабильности кадров (то есть сдвига фазы) многопроцессорные решения будут создавать кадры с переменным интервалом времени, что означает два следствия:
Одиночная видеокарта обладает теми же недостатками, но у нее результаты расчета поступают четко без расхождения четного-нечетного кадра, в отличии от SLI/CF. Разницу можете оценить сами, приведу два варианта.
Раз:
Два:
Особенно красноречиво выглядит окно потока кадров. В первом случае получаем «эквивалентные» 39 FPS, во втором – 60 и без каких-либо пропусков.
Если с этим разобрались, то можно перейти к еще более запущенному случаю.
Вариант номер 3 – «ну, влияет».
Что же происходит, если жесткая кадровая синхронизация отключена? Система кэширования остается прежней, меняется лишь принцип работы с выходным буфером. При включенной синхронизации его обновление могло осуществляться только в момент активного состояния Vsync, пока информация не выводится на монитор. Если синхронизация отключена, то этой жесткой привязки нет и обновление может произойти в любой момент времени.
О дефектах изображения я упоминал ранее, сейчас нас больше интересует сам механизм взаимодействия. В работе видеокарты используется кэширование, что вызывает неявную кадровую синхронизацию, но ее эффективность мала. При приходе «лишнего» кадра драйвер может или его игнорировать (не исполнять) или «перезаписывать» текущий. Первое он сделать не имеет права, поэтому сосредоточимся на втором варианте.
Переполнение буфера «pre-rendered» осуществить невозможно, API Direct3D/драйвер просто не позволят вызывающему потоку положить на исполнение кадров больше, чем разрешено. Иначе говоря, скорость выдачи кадров зависит исключительно от того, как быстро видеокарта их обрабатывает. Не особо мудреная мысль, если подумать. Если видеокарта способна обработать больше, чем способен вывести интерфейс на монитор, то возникают «лишние» кадры. Эти кадры перезаписывают только что начавшийся вывод «правильных» кадров.
А именно, за время интервала одного Vsync создаются два (и более) кадров. Вначале, желательно по событию Vsync, в выходной буфер помещается нормальный кадр, потом он перезаписывается другим (а далее третьим-четвертым и так далее), пока не наступит время следующего Vsync. На мониторе это выглядит как сборник полей – верх от одного кадра, середина от другого, низ от третьего (и так далее), в местах соединения может наблюдаться разрыв. Думаю и так понятно, что мера искажений зависит от статичности изображения – если движение отсутствует, то все кадры выглядят одинаково и искажений не будет. Чем больше окажется разность в кадрах, тем выше дефектность.
Ранее приводились модели при включенной синхронизации. Если ее отключить, то получится примерно следующее:
При клике на картинку выше откроется «ускоренная» версия модели, можете оценить качество получаемой картинки с отключенной синхронизацией. Принцип работы модели тот же, что и у приводимых ранее – слева показан блок формирования изображения (строятся три цифры), в середине состояние буфера вывода, справа – информация, передаваемая на монитор. По сравнению с предыдущими моделями, здесь присутствуют два отличия: в два раза увеличена скорость формирования кадра и не используется жесткая привязка времени копирования кадра в выходной буфер.
Когда изображение формирует одиночная видеокарта (с одним графическим процессором) с отключенной кадровой синхронизацией, то ее поведение хорошо предсказуемо – при снижении или завышении скорости кадров над периодом Vsync происходит исчерпание (или насыщение) системы кэширования и выходной поток кадров повторяет временные соотношения поступающих данных на построение (по сигналу Present).
Понятное дело, что эта связь не «жесткая», временные затраты на обработку вносят свои поправки, но как «первое приближение» это работает. То есть логи FRAPS отражают качественное описание картинки. Однако напомню, что кратковременные «возмущения» могут исправляться системой кэширования в видеокарте, а потому здесь стоит говорить только о стационарных, медленно меняющихся процессах.
Переход на многопроцессорную обработку означает получение нескольких потоков кадров со сложной фазовой связью. Например, для типичного решения SLI/CF свойственно использование двух видеокарт, а это означает наличие двух потоков. Повторю иллюстрацию, которую приводил ранее:
На приведенной модели скорость формирования кадров каждой видеокартой одинакова и постоянна во времени, но реальные приложения (игры) такой стабильностью не обладают. Возьмем какую-нибудь игру на продукции фирмы NVIDIA, для разнообразия:
Одиночная видеокарта, но в течение небольшого отрезка времени (пять секунд) отмечаются состояния с различной стабильностью кадров – слева и в центре картинки они уже существенные, справа нестабильность практически исчезла. Виновником появления дефекта может быть сама игра, но кого это интересует? Важно лишь, что видно на экране.
Предположим, что был собран вариант SLI/CF на таких видеокартах и фазовый сдвиг между ними одинаков и неизменен (идеальный вариант). Таким образом, обе видеокарты будут поставлять кадры с длительностью формирования кадров 7-30 мс (30-140 Гц), примерно такой «разброс» кадров на центральной части приведенной картинки. Выходной буфер передатчика на монитор выбирает кадры поочередно из одной и другой видеокарт. Это означает, что разброс значений 7-30 мс одной карты превращается в... знаете, я затрудняюсь написать формулу пересчета, получаются отрицательные числа.
Положим, первая формирует (нечетные) кадры с интервалами 7, 30, 7, 30 мс или время 7, 37, 44, 74. Вторая плата получила схожую последовательность, только со сдвигом 180 градусов: 30, 7, 30, 7 мс или время 30, 37, 67, 74 мс. Фазовый сдвиг между потоками неизвестен, положим наилучший вариант ((30+7)/2 = ~20 мс), что дает временные отсчеты второго потока 50, 57, 87, 94. Коммуникатор на выходе должен выбирать отсчеты из первой и второй плат поочередно, что означает следующее соотношение:
| Номер кадра | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| Видеокарта № 1 | 7 | - | 37 | - | 44 | - | 74 | - |
| Видеокарта № 2 | - | 50 | - | 57 | - | 87 | - | 94 |
В данной последовательности только первый и последний отсчет находится на своем месте, все остальное напоминает кашу. Что с этим делать контроллеру в ведущей плате? У него есть кэширование на один Vsync, поэтому задержать третий отсчет (37 мс) до прихода второго (50 мс) он сможет, но его ресурсы не беспредельны – отсчет №5 (44 мс) придет раньше №2 (50 мс). В этой ситуации контроллер может приостановить конвейер платы №1, если она была «ведущей», но для «подчиненной» выполнить эту процедуру будет много сложнее и потребует явной аппаратной поддержки.
Возможно, это одна из причин, почему NVIDIA не распространила функцию стабилизации потока кадров, реализованную в 6хх серии, на предыдущие поколения? Короче говоря, велик шанс выбрасывания кадра. Да, полноценный сформированный кадр будет выброшен, как бы неприятно это не звучало. При этом программы типа FRAPS отметят его наличие, хотя на монитор он не попадет. Впрочем, если FRAPS этих «мелких дефектов» и не видит (ему они неинтересны), то вовсе не обязательно, что драйвер о них не в курсе и эту информацию получить совсем нетрудно, без какого-то специального аппаратного мониторинга.
Короче говоря, переход на SLI/CF приводит к резкому возрастанию «дефектности» в работе игры, причем это сильно зависит от самой игры. Я приводил ранее картинку «Dirt 2» для NVIDIA, позвольте ее повторить:
Как говорится, «ну вот». Остается только добавить аналогичную картинку в редакции AMD:
Игра – игрой, но драйверы тоже что-то значат. Или аппаратура.
Впрочем, вернемся к нашим баранам. Многопроцессорная обработка увеличивает «дефектность» поступления кадров, уже присутствующую в игре, но интересен и другой момент – размер кадров на выходной картинке. Например, создаются два кадра со скоростью, превышающую кадровую развертку в 2 раза. Это означает наличие на изображении монитора двух кадров одновременно. Понятное дело, что два кадра, один поверх другого, вывести невозможно, картинка на мониторе плоская, хотя и пишут «3D». На экране будет видна часть одного кадра и часть другого. Логично, но есть и особенности:
Опять хочется высказаться по недостаткам отключения кадровой синхронизации, но воздержусь.
Переход от одиночной видеокарты к SLI/CF решениям приведет к тому, что размер фрагментов и положение на экране станет очень нестабильным. Если частота кадров высокая, то глаз менее чувствителен к подобным проявлениям нестабильности и особых беспокойств сие не вызовет, если только не происходит нарушение линейности объектов. Разрыв и сдвиг дерева, как и похожие неприятности, будут заметны всегда и очень четко.
Иначе говоря, переход на SLI/CF может дать сильное ухудшение картинки там, где она и так плохая. Если же картинка нормальная, то и вред минимален.
Возвращаемся к Vsync.
Когда измеряют производительность, то кадровую синхронизацию отключают. Это правильно, иначе получали бы нечто несуразное. Но анализ кадров не представляет главного – как именно (точнее «что именно») мы получаем на мониторе. Есть логи, может возможно провести «обратное преобразование» и получить информацию по формированию изображения? Увы, FRAPS не представляет отсчетов кадровой синхронизации, да и команды «Present» не очень жестко отождествляют состояние выходного кадра, но попробовать-то можно?
Вполне очевидно, что происходит с кадром, когда он попадает в буфер вывода – он будет выдаваться на экран до тех пор, пока его не сменит другой кадр. Если включена вертикальная синхронизация, то переключение произойдет во время «обратного хода луча» (устаревшее понятие), то есть при активном состоянии сигнала Vsync. Если синхронизация отключена, то в любой момент, как только кадр поступит.
Попробуем решить непосильную задачу – можно ли, и как, перевести лог FRAPS в то, что показывается на экране. Если синхронизация включена, то перевод очень прост... но, скажите на милость, кто будет снимать лог производительности при включенном Vsync? Вариант отпадает, да и какой-то он нежизненный – мало кто включает кадровую синхронизацию, очень уж велики потери.
Остается случай с отключенной синхронизацией, и здесь большое поле для догадок. Влияние буфера «pre-rendered» очевидно и легко учитывается. То же относится к двойной и тройной буферизации на выходных кадрах построения, но как учесть переменное время выполнения на конвейере графического процессора? Увы, только «в первом приближении», FRAPS сильно обрезает полученную информацию. Можно воспользоваться собственной программой мониторинга, но это будет, как сказано в одном известном советском мультфильме, «совсем другая история» («Падал прошлогодний снег»).
Для проверки правильности применим данные предположения на реальных логах.
Интерес представляет число красного цвета на верхнем графике и «Avg» в статистике. Народ, просыпайтесь.
В данном случае это 26.5 и 26.6 – цифры довольно близки. Другой вариант:
Приложение не совсем игровое, но тоже использует DirectX – просмотр фильма с частотой кадров 29.975 Гц. Среднее число по логу FRAPS возвращает 29.9 Гц, пересчет в кадры - 29.8, результат совпадает. Еще вариант:
Другой плеер, другой фильм, другие частоты (не кратные частоте кадровой синхронизации), а результат схожий – частота кадров по Vsync примерно равна средней частоте кадров лога FRAPS. То есть формулировки наличия и отсутствия кадра соответствуют действительности (точнее, не вступают с ним в явное противоречие).
Поговорим несколько об ином – числовой оценке качества получаемого изображения. В качестве этого критерия используется «FPS» (число кадров в секунду). С одной стороны, это логично, чем выше количество кадров, тем быстрее обновляется изображение и тем меньше задержка вывода – отсюда «легкость» управления. «Задержка формирования изображения» выходит за рамки данной статьи, ограничимся лишь первой характеристикой – FPS. Выше равно лучше, откуда сомнения? Но, увы, не существует настолько мощных 3D-ускорителей и центральных процессоров, способных обеспечивать высокий и стабильный Frame Rate.
Скорость поставки кадров, которая может не совпадать со скоростью вывода (из-за выключенной кадровой синхронизации), меняется во времени. Чем резче происходят изменения, тем сильнее ломается моторика управления в игре. Другой типичный дефект – видеокарта не успевает сформировать кадр перед началом вывода кадра и он пропускается. Картинка на мониторе совсем не «лампочка» и нормальное состояние или «пропуск кадра» вовсе не соответствуют включенному или выключенному источнику света.
Возьмем два крайних случая:
Чаще всего пропуск кадра происходит не в столь контрастных ситуациях, поэтому «видимость» искажений не столь категорична. Если учесть, что и для самого «тяжелого» сценария нет четких границ дефектности, то определение «пропуска кадра» как прямого числового выражения качества изображения весьма размыто и в обычных случаях в нем еще меньше смысла.
Однако можно применить еще один вариант прочтения «отсутствующего кадра». Определение звучит так – если за время интервала кадровой синхронизации приходит хотя бы один кадр, то результирующий считается присутствующим. Иначе «пропуск». Данное определение несет смысл лишь при отключенной синхронизации и, для простоты, я опустил действие буферизации данных. Но, давайте подумаем, что происходит, когда кадр приходит позже положенного времени. Кадр помечается «пропущенным», ведь блок вывода начал повторную прорисовку на мониторе того же изображения.
Но, повторюсь, если синхронизация отключена, приход нового кадра означает его переписывание в буфер вывода. Здесь, опять же, есть условия и ограничения, но подобная ситуация вполне реальна. Если кадр задержался немного, то успеет вывестись на монитор небольшая часть старого кадра, после чего последует новый. Другими словами, «пропуск кадра» будет не на весь кадр, а лишь на небольшую часть, что позволяет говорить об «эффективном» пропуске, который меньше измеренного по скорости кадров лога FRAPS обратно пропорционально задержке появления нового кадра. Грубо говоря, если кадр не успел совсем чуть-чуть, то его необходимо засчитывать почти как полноценный кадр, а если пришел к самому концу интервала Vsync, то как почти полный пропуск кадра.
Для опробования этих технологий подсчета в программе, в верхнем окне, проводится подсчет кадров с учетом заметности глазом (число зеленого цвета) и подсчет пропущенных кадров с учетом времени появления следующего кадра (отсчет желтого цвета). Сами измерения носят экспериментальный статус и, по большому счету, ничего «численного» не представляют. Но с чего-то же надо начинать.
Зачем эти премудрости? Скорость потока кадров, FPS, принято использовать как меру производительности видеокарты и/или какой-то конкретной игры, но только она мало что значит, если к ней не добавлять описание «качество» изображения. Две парные характеристики уже представляют нечто осмысленное, вот только как производить оценку двумерных величин? Одна игра (видеокарта) дает 40 FPS при качестве 90 процентов, другая – 60 FPS при 40%, и как их сравнивать? Наиболее логично перевести описание свойств в одно число, «эффективные» FPS, только...
Да нет, проблемы не в формуле пересчета, а в результате, причем трудности психологические – после перевода от измеренных FPS (естественно, речь идет только об average FPS) к «эффективным» число может возрасти. Вот отсюда и «...».
Для пояснения действия возьмем что-нибудь определенное, например просмотр фильма (25 Гц):
Интерес представляет только верхний график.
Зеленый график предсказуем, при формировании 25 кадров в секунду на мониторе с частотой кадровой синхронизации 60 Гц вполне очевидно дает постоянный пропуск 1-2 кадров. Данные прямого подсчета кадров по Vsync (красный график, 24.9) практически совпадает с реальными (фильм 25 Гц).
В данном случае больший интерес представляет «желтый» график. Довольно наглядно видно, что задержка появления нового кадра от начала интервала Vsync не одинакова. Природа этого явления заключается в «не кратности» частоты развертки (60 Гц) и фильма (25 Гц). Если взять фильм 30 Гц, картинка изменится:
Программа зачем-то впихнула лишний пропуск в начало, поэтому результат несколько меньше ожидаемых 30 Гц, но это не важно – отчетливо видно, что новый кадр всегда приходит в одно и то же время, перед приходом каждого второго Vsync.
Посмотрим некоторые игры для одиночных видеокарт и SLI/CF, при этом расширив номенклатуру мониторов другим типичным значением частоты кадровой синхронизации 120 Гц.
NVIDIA GeForce GTX 570
| «NVIDIA» | Монитор 60 Гц | Монитор 120 Гц | |||||
| Название игры | Средняя частота кадров | С учетом заметности | С учетом раннего кадра | По сигналу Vsync | С учетом заметности | С учетом раннего кадра | По сигналу Vsync |
| NVIDIA GeForce GTX 570 | |||||||
| Arcania | 66.3 | 58.4 | 57.9 | 57.9 | 84.7 | 78.3 | 66.3 |
| BFBC2 | 64.8 | 58.9 | 58.7 | 58.5 | 81.9 | 76.9 | 64 |
| Crysis 2 | 63.9 | 59 | 58.8 | 58.8 | 83.1 | 77.6 | 64 |
| Dirt 2 | 67.7 | 59.2 | 59.1 | 59 | 82.8 | 79.2 | 67.3 |
| Dragon Age 2 | 63.9 | 59.3 | 59.2 | 59.2 | 84.7 | 77.6 | 63.6 |
| F1 2010 | 62.7 | 59.7 | 59.6 | 59.6 | 81.2 | 76.3 | 59.9 |
| Mafia 2 | 82.9 | 56.9 | 56.7 | 56.4 | 89.2 | 87.5 | 82.1 |
| Metro 2033 | 68.6 | 57.5 | 57.4 | 57.2 | 84.2 | 80.4 | 67.8 |
| Shogun 2 | 61.7 | 59.6 | 59.6 | 59.6 | 85.3 | 79.7 | 62.7 |
| S.T.A.L.K.E.R. | 64.5 | 58.7 | 58.4 | 58.4 | 83.7 | 79.1 | 67.2 |
| NVIDIA GeForce GTX 570 х2 SLI | |||||||
| Arcania | 74.3 | 59.3 | 59.1 | 59.1 | 86.7 | 81.4 | 73.2 |
| BFBC2 | 81 | 59.3 | 59.1 | 59 | 89.3 | 86.7 | 79.1 |
| Crysis 2 | 116.3 | 59.7 | 59.7 | 59.7 | 96.9 | 92 | 87.8 |
| Dirt 2 | 82.2 | 59.4 | 59.4 | 59.3 | 90.3 | 88 | 81.5 |
| Dragon Age 2 | 82.7 | 59.5 | 59.4 | 59.4 | 90.4 | 88.3 | 81.5 |
| F1 2010 | 77.8 | 59.4 | 59.3 | 59.3 | 88.1 | 85.2 | 77.4 |
| Mafia 2 | 85.5 | 57.7 | 57.4 | 57.3 | 90.5 | 89.2 | 83.6 |
| Metro 2033 | 90.4 | 57.9 | 57.7 | 57.6 | 90.4 | 89.7 | 82.5 |
| Shogun 2 | 75.3 | 59.1 | 59.1 | 59 | 86.2 | 81.9 | 74.1 |
| S.T.A.L.K.E.R. | 76.9 | 59.6 | 59.6 | 59.6 | 88.2 | 85.7 | 76.7 |
AMD Radeon HD 5850
| «AMD» | Монитор 60 Гц | Монитор 120 Гц | |||||
| Название игры | Средняя частота кадров | С учетом заметности | С учетом раннего кадра | По сигналу Vsync | С учетом заметности | С учетом раннего кадра | По сигналу Vsync |
| AMD Radeon HD 5850 | |||||||
| Arcania | 64 | 58.6 | 58.3 | 58.2 | 81.9 | 75.7 | 62.3 |
| BFBC2 | 64.5 | 58.9 | 58.7 | 58.6 | 82.8 | 77.7 | 65.6 |
| Crysis 2 | 67 | 58.8 | 58.9 | 58.7 | 83 | 78.5 | 67.1 |
| Dirt 2 | 61.7 | 58.9 | 58.8 | 58.7 | 81.1 | 76.5 | 59.6 |
| Dragon Age 2 | 63.5 | 59 | 58.8 | 58.8 | 84.2 | 77.2 | 64.6 |
| F1 2010 | 61.7 | 59.4 | 59.3 | 59.3 | 83.7 | 78.9 | 63.2 |
| Mafia 2 | 72.9 | 57.6 | 57.9 | 57.7 | 84.6 | 81.8 | 73.5 |
| Metro 2033 | 66.9 | 55.8 | 55.3 | 55 | 81.5 | 85.6 | 67.2 |
| Shogun 2 | 61.5 | 57.7 | 57.5 | 57.5 | 80.3 | 76.6 | 61.6 |
| S.T.A.L.K.E.R. | 68.8 | 58.3 | 58.6 | 58.2 | 82.8 | 78.2 | 67.7 |
| AMD Radeon HD 5850 х2 CrossFireX | |||||||
| Arcania | 74 | 58.4 | 58.1 | 58 | 86.6 | 82.5 | 74.6 |
| BFBC2 | 103.3 | 59.2 | 59 | 58.9 | 95.3 | 93.9 | 87.9 |
| Crysis 2 | 117.6 | 60 | 60 | 60 | 97.2 | 91.8 | 88.4 |
| Dirt 2 | 104.3 | 59.8 | 59.8 | 59.8 | 94.2 | 92.3 | 86.5 |
| Dragon Age 2 | 93.3 | 59.7 | 59.6 | 59.6 | 93.5 | 91.3 | 84.6 |
| F1 2010 | 88.2 | 59.8 | 59.7 | 59.7 | 92.2 | 91.5 | 84 |
| Mafia 2 | 80.9 | 58.1 | 58.5 | 58.4 | 87.3 | 85.4 | 78.5 |
| Metro 2033 | 74.9 | 58.3 | 58.1 | 58 | 86.9 | 84.6 | 72.3 |
| Shogun 2 | 70.3 | 59.8 | 59.8 | 59.8 | 85.1 | 81.3 | 70.4 |
| S.T.A.L.K.E.R. | 81.3 | 58.3 | 58.5 | 58.3 | 87 | 84.2 | 77.9 |
AMD Radeon HD 6970 / HD 6990
| «AMD» | Монитор 60 Гц | Монитор 120 Гц | |||||
| Название игры | Средняя частота кадров | С учетом заметности | С учетом раннего кадра | По сигналу Vsync | С учетом заметности | С учетом раннего кадра | По сигналу Vsync |
| AMD Radeon HD 6970 | |||||||
| Arcania | 62.6 | 58.6 | 58.2 | 58.2 | 82.2 | 76.7 | 61.2 |
| BFBC2 | 63.6 | 58.7 | 58.3 | 58.3 | 81.6 | 76.4 | 63.1 |
| Crysis 2 | 67 | 58.7 | 58.8 | 58.5 | 83.8 | 78.7 | 68.8 |
| Dirt 2 | 61.9 | 59.2 | 59.1 | 59.1 | 83.8 | 79.4 | 63.9 |
| Dragon Age 2 | 64.6 | 59.2 | 59 | 59 | 83.9 | 79.7 | 66.1 |
| F1 2010 | 61.2 | 59.4 | 59.3 | 59.3 | 83 | 79.3 | 60.9 |
| Mafia 2 | 71.9 | 57.8 | 57.9 | 57.8 | 84 | 80.7 | 72.2 |
| Metro 2033 | 67.8 | 56 | 55.4 | 55.1 | 81.4 | 78.2 | 65.2 |
| Shogun 2 | 61.7 | 58.3 | 58.1 | 58.1 | 80 | 76.6 | 60.5 |
| S.T.A.L.K.E.R. | 69.9 | 57.9 | 58.2 | 57.6 | 83.2 | 78.3 | 70.4 |
| AMD Radeon HD 6990 (CrossFireX средствами одной видеокарты) | |||||||
| Arcania | 74.9 | 58.6 | 58.3 | 58.2 | 86.2 | 81.1 | 74.3 |
| BFBC2 | 107.1 | 58.6 | 58.4 | 58.3 | 95.3 | 90.8 | 86.3 |
| Crysis 2 | 118.6 | 59.7 | 59.7 | 59.7 | 97.2 | 92.7 | 89 |
| Dirt 2 | 104.2 | 59.7 | 59.7 | 59.6 | 93.5 | 92.3 | 86 |
| Dragon Age 2 | 98.1 | 59.4 | 59.3 | 59.2 | 93.6 | 91.1 | 84.7 |
| F1 2010 | 132.5 | 60 | 60 | 60 | 118 | 118 | 118 |
| Mafia 2 | 88.4 | 57.9 | 58.1 | 58 | 89.9 | 89 | 83.3 |
| Metro 2033 | 79.7 | 57.5 | 57.4 | 57 | 86.4 | 83.2 | 73.9 |
| Shogun 2 | 69.7 | 59.3 | 59.5 | 59.4 | 83.8 | 80 | 69.1 |
| S.T.A.L.K.E.R. | 96.2 | 58.8 | 58.9 | 58.8 | 93.3 | 91.3 | 85.9 |
Интересно, хоть кто-нибудь попробует посмотреть эти таблицы? Вряд ли, ну да ладно.
К сожалению, при съеме информации автор статьи «AMD CrossFireX под микроскопом. На примере Club3D HD 6990» очень ответственно подошел к настройкам в тестируемых играх, поэтому данные для обычного монитора с частотой развертки 60 Гц особого смысла не несут, ведь большую часть времени поток кадров оказывался выше критической величины и обязательно наступит «насыщение».
Впрочем, даже при среднем FPS выше 60 после приведения к синхроимпульсам оказалось, что цифру «60» или близкую к ней смогли предоставить лишь отдельные игры. Есть повод задуматься о выборе 120-герцового монитора, но не в данной статье – она и так перегружена очевидными характеристиками. Придется воспользоваться вариантом анализа под монитор 120 Гц. Хоть и не самое распространенное, но все же встречающееся у любителей игр решение.
В качестве оценки предполагаемых способов определения скорости кадров сами игры не интересны, как и их настройки. Важно лишь, что все видеокарты и их комбинации тестировались в одинаковых условиях. Вычислим среднее значение по играм, это позволит снизить ошибку и уменьшить разброс показаний.
Усредненная характеристика по всем играм при эмуляции монитора 120 Гц.
| Название видеокарты | Средняя частота кадров | С учетом заметности | С учетом раннего кадра | По сигналу Vsync | Прибавка раннего кадра |
| NVIDIA GeForce GTX 570 | 66.7 | 84.1 | 79.3 | 66.5 | 12.8 |
| NVIDIA GeForce GTX 570 х2 SLI | 84.2 | 89.7 | 86.8 | 79.7 | 7.1 |
| AMD Radeon HD 5850 | 65.2 | 82.6 | 78.7 | 65.2 | 13.5 |
| AMD Radeon HD 5850 х2 CrossFireX | 88.9 | 90.5 | 87.9 | 80.5 | 7.4 |
| AMD Radeon HD 6970 | 65.2 | 82.7 | 78.4 | 65.2 | 13.2 |
| AMD Radeon HD 6990 (2 GPU) | 96.9 | 93.7 | 91 | 85 | 6 |
Возьмем среднюю величину по прибавке от раннего кадра для одиночных и SLI/CF решений:
| Топология | Прибавка раннего кадра |
| Одиночная видеокарта | 13.2 |
| SLI/CF | 6.8 |
Можно поспорить о разумности учета раннего прихода кадра, но его применение к разным топологиям представляет четкий и, что удивительно, предсказанный результат – одиночные видеокарты дают менее «шумную» картинку.
Учет раннего кадра основан на том, что пропуск кадра часто не бывает полным, лишь начало вывода кадра начинается со старого и затем он замещается новым. Чем стабильнее видеосистема формирует кадры, тем меньше их взаимный разброс по времени. В логах FRAPS отсутствуют временные метки, поэтому анализатор пытается так подобрать начальное смещение внутри последовательности, чтобы получить наибольшее значение частоты кадров по Vsync.
Качество картинки на экране
В этом разделе будут использоваться данные измерений, снятые на одной-двух видеокартах AMD Radeon HD 6970.
Возьмем какую-нибудь игру и посмотрим поведение картинки при скорости потока кадров больше, чем частота кадровой развертки. Естественно, привязка к Vsync будет отключена.
Для получения качественных результатов, а не только «эстетических», в каждом кадре будет формироваться контрольный признак кадра (аналог его номера) – линия с левого края экрана, по всей его высоте. Положение (и цвет) линии определяется номером кадра. В результате на экране будет наблюдаться «движение» линии в некоторой начальной области, от его левого края. Метод вывода картинки на монитор заключается в последовательной передаче строк, поэтому визуальная картинка будет отражать длительность показа каждого кадра. Например, при удвоенной скорости формирования в пределах одного показанного кадра будет две части – от одного кадра и от второго, а длина цветных линий будет прямо пропорциональна длине этих частей.
Интерес представляет все, что выше 60 к/с и для удобства наблюдения выберу сцену с удвоенной скоростью кадров (120 Гц). Благодаря наличию маркеров я мог наблюдать соотношение длительности фрагментов и мог выбрать момент, когда их соотношение было примерно правильным (50/50%) с последующим плавным «уходом». Визуально трудно оценить соотношение длин маркеров, если они сами двигаются, поэтому, очень грубо, соотношение поменялось на что-то около 25/75. При этом снимался лог и на него взглянуть стоит:
Мониторинг зафиксировал именно то, что я видел глазами. В самом начале длительности «выровнялись» (что и должно происходить при соотношении 50/50), и затем плавно «разошлись» до 1.5:1. Что же, этот тест показывает логические предпосылки, использованные при построении анализатора – поток кадров по сигналу «Present», захватываемый программами типа FRAPS, отражает то, что происходит на экране, хотя бы «качественно». Конечно, по одному тесту довольно трудно сделать однозначный вывод, но факт практического подтверждения вселяет оптимизм. Впрочем, по результатам практической части статьи уровень оптимизма резко убудет.
И, увы, вынужден отметить крайне печальное наблюдение. При включении режима «Benchmark» в программе FRAPS линии мониторинга резко изменили картинку. Это означает, что в данном режиме программа FRAPS (использовалась версия 3.5.99) вносит дополнительную нагрузку, что вызывает искажение результатов.
Проведем простую проверку – включим формирование лога другой программой, а затем запустим «Benchmark» FRAPS. Условия те же, примерно 120 FPS.
На картинке отмечены три участка – начальный этап сбора статистики примерно 10 секунд, затем выполнялся захват FRAPS на 15 секунд. Эти события четко отождествляются по «странному» провалу скорости кадров, я их дополнительно отметил маркерами. Судя по логу, ошибки, создаваемые FRAPS, действуют не очень продолжительное время и эти фрагменты могут быть отброшены при последующем анализе. Но увы, эффект неожиданный и очевидно отрицательный.
Скорее всего, в момент включения/выключения выполняется какая-то сторонняя деятельность (вариант – файловые операции), которые загружают систему. Почему нельзя было выполнить буферизации измерений, неужели желание сэкономить память? Осадок неприятный и для тонких измерений FRAPS не очень подходит.
На этом позвольте завершить теоретическую часть материала. Вопросы, оказавшиеся за кадром:
Продолжение следует…