Любой, кто хоть раз прогонял бенчмарк на свежей видеокарте, видел красивую цифру среднего FPS и радовался жизни. Потом запускал игру, ловил рывки на ровном месте и чесал затылок: ведь счётчик показывал сотню кадров в секунду, а картинка дёргалась так, словно девяностые вернулись. Разгадка проста и неприятна одновременно: FPS - это усреднённая величинаuirements, которая считает сколько кадров уложилось в секунду, а время кадра - это мгновенная длительность каждого отдельного кадра в миллисекундах. Между ними пропасть, и именно в этой пропасти прячутся все статтеры, микрофризы и ощущение что картинка "не едет". В этой статье разберём разницу на костях разбора реальных прогонов: почему ровные 60 FPS с кадром 16.6 мс ощущаются глазом плавнее, чем условные 120 FPS с пилообразными скачками 4/20/8/16 мс, где именно в конвейере рождаются рывки, как читают графики frame time анализаторы вроде PresentMon, и почему консольные тридцать ровных кадров порой воспринимаются лучше, чем сорок пять скачущих на ПК.

Две величины, одна секунда

Начнём с арифметики, потому что она тут обманчива. FPS - кадры в секунду, величина обратная. Время кадра - миллисекунды на кадр, величина прямая. Пересчёт элементарный: 1000 делим на FPS и получаем средний бюджет кадра. 60 FPS - это 16.6 мс на кадр. 144 FPS - уже 6.9 мс. 30 FPS - целых 33.3 мс. Казалось бы, какая разница, в чём мерить, если это одно и то же, записанное наизнанку. Разница есть, и она двойная.

Во-первых, шкала нелинейна. Прирост с 30 до 40 FPS освобождает больше восьми миллисекунд на кадр - с 33.3 до 25. А прирост со 100 до 110 FPS даёт меньше одной миллисекунды. Маркетинг обожает большие числа слева на шкале, но человеческий глаз питается миллисекундами, и они исчезают с другого края. Во-вторых, и это главное, FPS удобно усреднять, а среднее - великий лжец. Секунда наблюдения вмещает сотню кадров, и если девяносто девять из них отрисовались за 4 мс, а один подвис на 100 мс, средний FPS честно покажет около 107, а глаз честно увидит заметный рывок. Среднее съело персональную историю выброса.

Время кадра, напротив, не усредняет ничего по своей природе. Каждый кадр - точка на графике. Тестировщик строит последовательность этих точек и видит рельеф: ровная линия - хорошая линия, пила - плохая пила. Скачок с 4 до 20 мс внутри секунды почти не двигает средний FPS, зато рубит восприятие плавности на куски, потому нейроны регистрируют не "сколько кадров в среднем", а "насколько непредсказуем следующий". Равномерность - валюта, в которой расплачивается плавность.

Почему пила на 120 проигрывает спокойным 60

Возьмём два воображаемых прогона. Первый - идеальные 60: каждый кадр ровно 16.6 мс, график времени кадра - линейка с отвёрткой. Второй - пилообразная сотня с лишним: кадры идут 4 мс, 20 мс, 8 мс, 16 мс, снова 4. Среднее время кадра у второго - около 12 мс, это более 80 FPS, статистика лучше. Ощущение хуже, и вот механика этого парадокса.

Глаз и рука - не интеграторы, а детекторы нарушения ритма. Когда кадры приходят с постоянным шагом, мозг строит ожидание, и движение читается как непрерывное. Когда шаг дышит - 4/20/8/16 - картинка в одной и той же секунде то несётся, то топчется, и стыки этих темповых фаз видны мельками и подёргиваниями траекторий. Особенно наглядно это при панорамировании камеры мышкой: скорость курсора постоянна, а визуальное движение мира - нет, мозг сразу фиксирует рассинхрон. Инженеры по вывозу мусора из кадров называют это нарушением frame pacing, равномерности доставки.

Есть и чистая математика восприятия. Разница между 4 мс и 20 мс - целых 16 мс неожиданной тишины на экране. Разница между 16.6 и 16.6 - ноль. Порог заметности одиночной паузы лежит где-то в районе нескольких десятков миллисекунд, но вот вариация подряд идущих кадров чувствуется уже при долях этой величины, особенно в динамичных сценах. Выброс в 30-40 мс на фоне потока по 8 мс - это фактически четыре пропущенных кадра подряд, микрофриз в чистом виде. ПоэтомуThat is why бенчмаркеры давно перековали линейки: смотрят не на средний FPS, а на процентили.

Процентили, дисперсия и джиттер

Профессиональный разбор лога начинается не со среднего, а с худшего. Метрика 1% low - средний FPS самой тяжёлой сотой доли кадров прогона. Метрика 0.1% low - то же для самой поганой тысячной доли. Эти две цифры показывают не то, как система летит в хороший день, а то, как она спотыкается, и именно спотыкания запоминает игрок. Игра со средними 144 и 1% low на уровне 58 ощущается не как 144, а как что-то ближе именно к шестидесяти, пересыпанное рывками.

Дальше две формальные меры. Дисперсия, variance - мера разброса длительностей кадров вокруг среднего бюджета. Чем выше разброс при том же среднем, тем "мохнатее" график времени кадра. Джиттер, jitter - вариация от кадра к соседнему кадру, фактически первая производная кривой. Дисперсия говорит что кадры разные, джиттер - что они ещё и внезапно разные. Мониторный прогон может иметь скромную дисперсию (кадр плавно утолщается по мере сцены), но катастрофический джиттер (толстые кадры в шахматном порядке с тонкими), и второй случай раздражает сильнее: резкий толчок на середину темпа воспринимается грубее, чем постепенный подъём нагрузки.

Практический вывод для стенда прижат к характеристикам человека. Зрительная система регистрирует отдельные стимулы вплоть до пауз порядка 10-13 мс в идеальных условиях и куда комфортнее - при 16-33 мс в реальном интерактиве, но ключевой порог восприятия не столько абсолютный, сколько относительный: пауза, вдвое превышающая базовый темп, уже считывается как рывок. Отсюда простая формула здоровья прогона: ширина столбиков на графике важнее высоты средней линии. Циановая линия графического оверлея - любимый инструмент обзорщиков - именно этим и ценна: она показывает временной ряд, и каждый зубец этой циановой линии - обещанный пользователю статтер.

Откуда берутся рывки и в чём состоит анатомия статтера

Пильчатая кривая не рождается из распространённой графики односущно. У неё всегда есть поставщики, и хороший тестировщик умеет их опрашивать по списку.

  1. Планировщик и очередь потоков. Игровой процесс соперничает за ядра с фоновыми службами, оверлеями и браузером с четырьмя десятками вкладок. Отнятый на планировщике квант оборачивается лишним ожиданием главного потока - и на графике растёт столбик.
  2. Сборка мусора. Движки на управляемых языках периодически останавливают мир для уборки кучи. Пауза сборщика в 10-30 мс - готовый статтер, особенно в открытых мирах с интенсивной аллокацией.
  3. Шейдерная компиляция на лету. Игра встречает новый материал или эффект, компилирует шейдер прямо в бою - и кадр уходит в подвисание на десятки миллисекунд. Классика первых часов после установки.
  4. Подгрузка ресурсов и стриминг текстур. Высокие текстурные наборы затягиваются с накопителя в видеопамять пачками; если квота VRAM исчерпана, начинается перекачка страниц по шине, и кадр ширится рывками.
  5. Очередь кадров и VSync. При традиционной вертикальной синхронизации кадры встают в очередь глубиной в два-три кадра; когда рендер чуть не дотягивает до очередного такта развёртки, кадр либо ждёт следующее окно (удвоение времени до 33.3 мс на 60 Гц), либо вызывает трыение - разрыв строки. Обе альтернативы хуже, чем кажется по средней цифре.

Отдельного пункта заслуживает frametime-разрыв между постановкой кадра процессором и его рисованием: игра может штамповать кадры быстрее, чем их глотает конвейер, образуя запасной буфер, и в нём переменная глубина очереди сама по себе складывается в неровный ритм вывода. Статтер - не про "плохую видеокарту", статтер - про "кто-то в цепочке не удержал темп".

VRR и адаптивные частоты как дезодорант неровности

Здесь начинается современная хитрость дисплейного стека. Классический монитор с фиксированной развёрткой VSync задаёт игре жёсткий утар: 60 Гц - окна по 16.6 мс, не успел - жди следующего, и длительность кадра прыгает дискретно, целыми окнами. Адаптивные технологии - VRR по стандарту DisplayPort Adaptive-Sync, фирменные G-Sync и открытый FreeSync - переворачивают схему: теперь не игра подстраивается под монитор, а монитор растягивает момент обновления под реальный кадр. Кадр готов за 12 мс - развёртка через 12 мс. Следующий собрался за 17 мс - подождём до 17. Дискретная лесенка исчезает, и неровности внутри рабочего диапазона VRR (условные 48-144 Гц) перестают конвертироваться в пропуски окон и разрывы.

Важна честность формулировки: VRR не лечит статтер, он маскирует взаимодействие статтера с vsync-окном. Рывок в 40 мс останется рывком и на адаптивном мониторе, просто он не будет удвоен ожиданием развёртки и не даст разрыва. Зато весь сочный диапазон мелкой неравномерности - скачки с 10 до 14 мс - визуально стирается, потому что экран выводит каждый кадр ровно тогда, когда он готов, сохраняя их взаимные интервалы. ПоэтомуSame поэтому два прогона с идентичным графиком времени кадра ощущаются по-разному на фиксированных 60 Гц и на FreeSync-панели: на первой зубцы пилы ещё и квантуются до 33 мс, на второй они проходят как есть.

Практический нюанс тестировщика: перед снятием логов надо решать методологический вопрос. С VRR график frame time отражает "сырое" поведение движка и позволяет сравнивать железо честно; с VSync-off появляется множитель tearing и интерпретировать кривую труднее; а VSync-on зашивает квантование в лог и делает сравнение статтеров косвенным. Серьёзные методики фиксируют режим в протоколе, иначе сравниваются не видеокарты, а режимы вывода.

Урок консолей, где ровные 30 обыгрывают скачущие 45

Удобный натурный эксперимент - консольные 30 FPS. Там бюджет кадра 33.3 мс, довольно грустная величина по меркам 144-герцовых панелей, но две вещи сделаны жёстко: стабильный frame pacing с ровным шагом и обязательный VSync в окне. Движок знает бюджет, профилируется под него годами и отдаёт каждый кадр в срок. На графике - идеальная тринадцатая линейка без зубцов. И знаете что? Играется сносно. Не "летает", но не раздражает - движение предсказуемо, и мозг быстро принимает этот ритм как базу.

Теперь ПК-сценарий: средний FPS порядка 45, но кадры скачут от 14 до 40 мс, потому что сцена чуть перегружает процессор, сборщик мусора заходит раз в три секунды, а очередь кадров дышит. Среднее лучше консольного на полтора раза, ощущение - хуже. Причина та же вариация: шаг кадра непредсказуем, рука делает равномерное движение мышью, а мир на экране отвечает рваным. Добавим фиксированные 60 Гц без VRR - и скачки округляются до 16.6/33.3, 45 аварийных превращаются в смесь из 30 и 60 в случайном порядке, что для восприятия хуже каждого из чистых режимов по отдельности.

Это даёт практическое правило, которым пользуются и разработчики, и матёрые игроки: если удержать высокий FPS стабильно не выходит - ограничивай его до ступени, которую система держит ровно. Кап в 60 через внутриигровой лимитер или внешний ограничитель кадров обрезает пики сверху, выравнивает бюджет и систематически ощущается приятнее, чем "разблокированные" 70-110 с пилой. Усреднённая величина терпит поражение от мгновенной - это и есть тезис всей статьи, подтверждённый обеими платформами.

Как измерять правильно через PresentMon и анализ логов

Осталась инструментальная часть, без неё разговор умозрительный. Отраслевой стандарт - PresentMon, открытый сборщик событий планировщика подачи кадров: он не считает FPS "на глазах" по оверлею, а регистрирует моменты Present каждого кадра и выдаёт лог с метками времени, который затем разбирают. Из лога строят временной ряд длительностей, считают средний FPS, медиану, процентили (в том числе те самые 1% low и 0.1% low), дисперсию и джиттер. Поверх работают визуализаторы и оверлеи - встроенные средства CapFrameX, RTSS с его графом frametime, внутренние анализаторы обзорных лабораторий. Аппаратная ветка анализа - высокоскоростная съёмка экрана и FLIR-подобные камерные методики: камера снимает сам монитор с частотой в тысячу кадров в секунду, и рывки фиксируются в реальном выходе - включая всё, что происходит после логики измерителя, вплоть до поведения развёртки. Это "золотой" контроль правды: лог говорит что кадр отдан, камера показывает что он показан.

Методика прогона определяет половину вывода. Правила стенда простые и жестокие: тёплый прогон после загрузки шейдерного кэша (иначе компиляционные статтеры замешаются в больную выборку), фиксированная сцена с повторяемой камерой, одинаковый режим вывода у всех участников, не менее трёх повторов с усреднением процентилей, закрытые фоновые хищники квантов. Результаты сводятся не одной цифрой, а строкой: средний FPS, время кадра медианы, 1% low, 0.1% low и комментарий по форме кривой. Одного среднего FPS в отчёте у приличного тестировщика нет уже лет десять - и это лучший комплимент теме статьи.

В сводку закладываем и конкретные вехи бюджета, чтобы читатель быстро переводил единицы в уме: 33.3 мс - 30 FPS, 16.6 мс - 60 FPS, 11.1 мс - 90 FPS, 8.3 мс - 120 FPS, 6.9 мс - 144 FPS, 4.2 мс - 240 FPS. Когда кто-то говорит "у меня 144", полезно сразу спросить: а худшая тысячная доля кадров укладывается в 6.9 мс или там живут двадцатимиллисекундные гости? Вот тут и начинается честный разговор о плавности - не тот, где большие числа слева на обложке, а тот, где ровная циановая линия уходит вдаль без единого зубца, и рука с глазом наконец перестают спорить друг с другом о том, что такое хороший кадр.