Бенчмарки кодеков Fastvideo JPEG и NVIDIA nvJPEG на RTX 4090

Обновлено:

В статье сравниваются два кодека JPEG на одной видеокарте RTX 4090: Fastvideo JPEG из Fastvideo SDK и библиотека nvJPEG из CUDA Toolkit. Таблицы квантования у них одинаковые, и качество сжатия практически одинаковое, поэтому сравнивается скорость. При кодировании кодек Fastvideo быстрее на 30–39 % (кадры 2K, 4K и 8K, один поток). При декодировании разница намного больше: декодер Fastvideo быстрее декодера nvJPEG в 9,7 раза на кадре 2K, в 28 раз на 4K и в 35 раз на 8K. Главная причина — рестарт-маркеры. Кодек Fastvideo вставляет маркеры в процессе сжатия, что позволяет ему потом декодировать эти изображения на видеокарте параллельно; при этом размер сжатого файла с маркерами увеличивается всего на 2,1–2,9 %. Кодек nvJPEG маркеры не вставляет и работать с ними не умеет. Поэтому от выбора кодека зависит не только скорость кодирования, но и скорость декодирования, причём наибольшее влияние этот выбор оказывает именно на декодирование.

График: кодирование и декодирование JPEG на RTX 4090, кадров в секунду у кодека Fastvideo JPEG и у библиотеки nvJPEG на кадрах 2K, 4K и 8K
Кодирование и декодирование при качестве 90, 4:4:4, без копирования на видеокарту и обратно. При кодировании скорость кодеков различается на проценты, при декодировании — в разы.

Эта статья есть и в виде PDF: Бенчмарки кодеков Fastvideo JPEG и NVIDIA nvJPEG на RTX 4090 (технический отчёт) — тот же текст, числа и графики, с оглавлением и номерами страниц, чтобы читать без сети и передавать дальше.

Главные результаты

RTX 4090, Fastvideo SDK 0.23.1.0 и nvJPEG 13.2.1.68. Скорость — в кадрах в секунду (к/с). Условия — стандартные для измерений этой статьи (раздел 2), если в пункте не сказано иное.

Скорость кодирования и декодированияОдин поток, без копирования на видеокарту и обратно, качество 90, 8 бит на канал, 4:4:4 (без прореживания цвета)
Тестовые
кадры
Кодер
Fastvideo
Кодер
nvJPEG
Декодер
Fastvideo
Декодер
nvJPEG
2K, 1920×10805595 к/с4313 к/с1862 к/с191 к/с
4K, 3840×21602805 к/с2014 к/с1640 к/с59,1 к/с
8K, 7680×4320715 к/с541 к/с515 к/с14,9 к/с
12K, 11520×6480335 к/с248 к/с221 к/с6,05 к/с
16K, 15360×8640191 к/с137 к/с118 к/с3,43 к/с
  • Кодирование: кодер Fastvideo быстрее кодера nvJPEG на 30–39 %.
  • Декодирование: декодер Fastvideo быстрее декодера nvJPEG в 9,7–37 раз.
  • Рестарт-маркеры: кодер Fastvideo вставляет их в сжатые кадры, а nvJPEG — нет. Размер файла с маркерами увеличивается на 2,1–2,9 %.
  • В каких случаях получается такая скорость декодирования: на изображениях с рестарт-маркерами — сжатых кодером Fastvideo или подготовленных программой jpegtran.
  • Большие разрешения, кадры 12K и 16K: кодер Fastvideo быстрее кодера nvJPEG на 35 и 39 %, декодер Fastvideo быстрее декодера nvJPEG в 37 и 34 раза. Производительность кодека Fastvideo выходит на насыщение уже на кадре 8K. Раздел 5.
  • Декодирование в многопоточном режиме, вместе с копированием на видеокарту и обратно: при оптимальном наборе параметров каждого кодека декодер Fastvideo быстрее в 3,0–3,3 раза.
  • Потребление энергии видеокартой при кодировании: с кодеком Fastvideo в 1,1–1,3 раза меньше, чем с nvJPEG.

Скрипты тестирования, наша программа для nvJPEG, сводки и логи всех измерений — на GitHub: github.com/fastvideo/jpeg-benchmark.

1. Рестарт-маркеры: что это и почему от них зависит скорость декодирования

Основную часть времени в алгоритме JPEG занимает не косинусное преобразование и не квантование, а энтропийное кодирование и декодирование.

Как устроен JPEG. Всё, о чём дальше идёт речь, описано в стандарте JPEG — ITU-T T.81, он же ISO/IEC 10918-1. Рассмотрим эту часть стандарта более подробно, эти термины нам пригодятся для понимания принципов работы кодека (в скобках — номера пунктов стандарта).

Как кодируются данные после рестарт-маркера. Коэффициент DC в JPEG кодируется не сам по себе, а как разность с коэффициентом DC предыдущего блока той же компоненты. После каждого рестарт-маркера кодирование коэффициентов DC начинается заново, с нуля. Сжатые данные перед маркером дополняются единичными битами до целого байта (п. B.1.1.5), чтобы маркер начинался с границы байта. Поэтому сегмент можно декодировать, ничего не зная о предыдущих: всё, что для этого нужно, есть в нём самом и в заголовке файла.

Как находятся маркеры. Маркер начинается с байта FF. Чтобы такой байт не появился внутри сжатых данных случайно, кодер после каждого байта FF в сжатых данных вставляет нулевой байт 00 — это называется byte stuffing, вставка байта (п. 3.1.14). Значит, пара FF и следующий за ним байт от D0 до D7 в сжатых данных — всегда рестарт-маркер, и найти все маркеры можно простым просмотром байтов, ничего не декодируя. Это позволяет сначала найти начала всех сегментов, а затем декодировать их одновременно — и это применение маркеров в стандарте названо прямо: «параллельное кодирование или декодирование» (п. 4.9).

Рестарт-интервалы кодера Fastvideo — фиксированные. Раньше рестарт-интервал был одним из параметров кодера, теперь это набор констант, своя для каждого типа прореживания; задать или изменить их нельзя. Значения приведены в руководстве к Fastvideo SDK. Они — компромисс между скоростью кодирования и скоростью декодирования. Декодер быстрее всего работает, если рестарт-интервал равен 1, то есть если кодер ставил маркер после каждого блока MCU, но тогда кодеру пришлось бы вставлять слишком много маркеров, он работал бы медленнее, а файл вырос бы на 21–29 % вместо 2,1–2,9 % (раздел 1.1). Во всех случаях в одном сегменте 30–32 блока 8×8.

Рестарт-интервалы кодера FastvideoПо руководству к Fastvideo SDK; для 4:4:4, 4:2:2 и 4:2:0 проверено по заголовкам файлов кодера; блоков 8×8 в сегменте — рестарт-интервал, умноженный на число блоков 8×8 в блоке MCU
Блок MCU,
пикселов
Блоков 8×8
в блоке MCU
Интервал,
блоков MCU
Блоков 8×8
в сегменте
4:4:48×831030
4:2:216×84832
4:2:016×166530
Моно­хромное8×813232

Про 4:2:2. Прореживание 4:2:2 значит, что цветоразностные компоненты уменьшены вдвое по горизонтали и не уменьшены по вертикали: на площадь 16×16 пикселов приходится 4 блока яркости и по 2 блока каждой цветоразностной компоненты. Стандарт позволяет записать это в заголовке двумя способами: множители 2×1 у яркости и 1×1 у цветоразностных компонент — тогда блок MCU занимает 16×8 пикселов и состоит из 4 блоков данных; или 2×2 и 1×2 — тогда блок MCU занимает 16×16 пикселов и состоит из 8 блоков данных. В таблице — первый способ, он встречается чаще, и именно его записывает кодер Fastvideo: мы сжали им кадр 4K с прореживанием 4:2:2 и прочитали заголовок файла — множители 2×1 у яркости и 1×1 у цветоразностных компонент, блок MCU 16×8 пикселов, рестарт-интервал 8 блоков MCU. Заголовок читает скрипт jpeg-sof-01.py из репозитория (раздел 13).

В этой статье измерены 4:4:4 и 4:2:0. Рестарт-интервал 1, то есть маркер после каждого блока MCU, кодер Fastvideo не использует: такие файлы для теста в разделе 1.1 сделаны другой программой.

При кодировании границы блоков известны заранее: их задаёт само несжатое изображение. Все блоки после квантования известны до начала энтропийного кодирования, поэтому каждый блок можно закодировать отдельно, а закодированные блоки потом сшить в один поток. Поэтому кодирование распараллеливается и без рестарт-маркеров.

При декодировании границы закодированных блоков неизвестны. Коды Хаффмана имеют переменную длину, и где кончается один код, становится известно только после того, как он разобран. Начать с середины нельзя, перескочить вперёд нельзя: пока данные не пройдены от начала, делить их не на что. Здесь и нужны рестарт-маркеры: только они делят сжатые данные на сегменты, каждый из которых можно декодировать независимо. Это похоже на книгу без оглавления и без номеров страниц: чтобы найти начало десятой главы, её приходится читать подряд с первой страницы. Рестарт-маркеры — это закладки в начале каждой главы: по ним сразу видно, где глава начинается, и разные главы могут читать одновременно несколько человек. Главы здесь — сегменты, а читатели — ядра видеокарты.

Это не наше изобретение и не расширение формата. Рестарт-маркеры описаны в стандарте JPEG с самого начала, и сделаны они именно для того, чтобы сегменты можно было декодировать независимо друг от друга. Эта возможность есть в стандарте больше тридцати лет и доступна любому, кто пишет кодек.

Тем не менее, мало кто пользуется этой возможностью. Причина в том, где JPEG работал всё это время. На центральном процессоре сегменты дают немного: потоков у процессора единицы, а не тысячи, и выигрыш не окупает нескольких процентов размера файла. Поэтому большинство кодеров маркеры не вставляет, а декодеры не умеют ими пользоваться — за ненадобностью, хотя с маркерами и один кадр декодировался бы быстрее. На видеокарте соотношение обратное: ядер тысячи, и именно нехватка сегментов не даёт их занять.

Кодер Fastvideo вставляет рестарт-маркеры всегда, а nvJPEG — никогда. Совместимость от маркеров не страдает: файл с ними читает любая программа, а декодер, который не умеет с ними работать, просто их пропускает.

Это подтверждают и результаты тестов: кодер nvJPEG работает на видеокарте быстро, хотя маркеры не вставляет, — при кодировании они ему и не нужны. Маркеры кодер вставляет не для себя, а для того, кто будет декодировать. В профилировщике прямо видно, что энтропийное кодирование у nvJPEG выполняется на видеокарте: при кодировании у него работают ядра ACKernel и DCKernel — это кодирование коэффициентов AC и DC, — и на них приходится почти половина всего времени ядер. У его же декодера ядра энтропийного декодирования нет вовсе. Подробнее об этом написано в разделе 7.

1.1. Одно и то же изображение с маркерами и без них: результаты теста

График: скорость декодирования одного и того же изображения JPEG с маркерами, без маркеров и с одним маркером на MCU, декодеры Fastvideo JPEG и nvJPEG, кадры 2K, 4K и 8K
Три варианта одного файла: с маркерами, как их вставил кодер Fastvideo, без маркеров и с маркером после каждого блока MCU. Скорость декодеру Fastvideo дают маркеры; декодер nvJPEG от маркеров почти не зависит.

Чтобы роль маркеров была не догадкой, а результатом теста, мы измерили её прямо. Изображение, сжатое кодером Fastvideo, переписано программой jpegtran из libjpeg-turbo ещё в два варианта: без маркеров и с маркером после каждого блока MCU. Программа jpegtran делает это без потерь: она не сжимает изображение заново и не меняет ни одного коэффициента. Она только заново выполняет энтропийное кодирование — убирает рестарт-маркеры или вставляет их с нужным рестарт-интервалом. После декодирования все три варианта дают побайтно одно и то же изображение. Оба декодера работали со всеми тремя вариантами, в один поток, без копирования на видеокарту и обратно.

Откуда взялась программа jpegtran. Это одна из утилит библиотеки libjpeg — свободной реализации JPEG, которую выпустила Independent JPEG Group, независимая группа разработчиков во главе с Томом Лейном. Первая версия библиотеки вышла 7 октября 1991 года, а jpegtran появилась в версии 6, в августе 1995 года. Программа преобразует уже сжатые файлы JPEG без потерь: она работает с квантованными коэффициентами и не выполняет декодирование полностью. Так она поворачивает и обрезает изображения, переводит файл из базового JPEG в прогрессивный и обратно, пересчитывает таблицы Хаффмана — и вставляет или убирает рестарт-маркеры. Программа jpegtran входит также в состав libjpeg-turbo — самого быстрого кодека JPEG для центрального процессора; он ускорен векторными инструкциями процессора и развивается с 2010 года. libjpeg-turbo распространяется свободно, есть в большинстве дистрибутивов Linux и в сборках для Windows.

С маркерами декодер Fastvideo работает в 19 раз быстрее на кадре 2K, в 53 раза быстрее на 4K и в 75 раз быстрее на 8K: 1864 к/с вместо 96, 1652 к/с вместо 31 и 527 к/с вместо 7. Без маркеров поток декодируется последовательно, и преимущества у декодера Fastvideo нет: nvJPEG на том же файле даёт 177, 55,9 и 14,8 к/с. Так и должно быть: как сказано в руководстве к Fastvideo SDK, на файле без маркеров, а также при рестарт-интервале больше 255, декодер Fastvideo выполняет энтропийное декодирование на центральном процессоре — так же, как nvJPEG. Всё преимущество декодера Fastvideo основано на маркерах.

Чем больше маркеров, тем быстрее декодирование. С маркером после каждого блока MCU декодер Fastvideo работает ещё на 77 % быстрее на кадре 2K и на 23 % быстрее на 4K и 8K. Цена такого варианта — размер: файл становится на 21 % больше, чем без маркеров, на кадре 2K и на 29 % больше на 4K и 8K, тогда как маркеры в том количестве, в каком их вставляет кодер Fastvideo, добавляют 2,1 % и 2,9 %. Сам кодер Fastvideo маркер после каждого блока MCU не вставляет: такой вариант файла получается только другой программой, здесь — jpegtran.

Декодер nvJPEG не умеет работать с маркерами. Файлы с маркерами он обрабатывает так же, как без них, — маркеры просто пропускает: 174 и 177 к/с на 2K, 52,7 и 55,9 к/с на 4K, 14,5 и 14,8 к/с на 8K. С маркером после каждого блока MCU он на 7–14 % медленнее: маркеров больше, и каждый приходится пропускать.

Декодирование одного и того же изображения в трёх вариантахОдин поток, качество 90, 4:4:4, без копирования на видеокарту и обратно
Fastvideo,
к/⁠с
nvJPEG,
к/⁠с
Fastvideo,
мс
nvJPEG,
мс
2K, с маркерами18641740,5365,74
2K, без маркеров9617710,45,64
2K, один маркер на MCU32961610,3036,21
4K, с маркерами165252,70,60519,0
4K, без маркеров3155,932,317,9
4K, один маркер на MCU203549,20,49120,3
8K, с маркерами52714,51,9069,0
8K, без маркеров714,814367,8
8K, один маркер на MCU65012,51,5479,7

Тест с маркерами — отдельная серия измерений в тот же день, поэтому результаты в строках «с маркерами» отличаются от раздела 4 не больше чем на 2,3 %: 1864 против 1862 к/с на кадре 2K, 527 против 515 к/с на 8K.

В многопоточном режиме, вместе с копированием на видеокарту и обратно, от маркеров так же зависит почти всё. Для изображений с маркерами декодер Fastvideo выдаёт 3800 к/с на кадре 2K и 896 к/с на 4K — это 93 % и 87 % пропускной способности PCIe, и скорость здесь ограничена уже пропускной способностью шины. Без маркеров — 869 и 255 к/с, на 77 % и 72 % меньше: несколько потоков декодируют разные кадры одновременно, но внутри каждого кадра декодирование остаётся последовательным. Маркер после каждого блока MCU прибавляет ещё 13 % и 3 %: дальше расти почти некуда, шина и так почти занята. На кадре 8K — 197 к/с с маркерами и 46 без них, на 77 % меньше; здесь работают 8 потоков: кадру такого размера больше не нужно.

Декодер Fastvideo на тех же трёх вариантах файлаМногопоточный режим вместе с копированием на видеокарту и обратно, качество 90, 4:4:4; 2K и 4K — 32 потока, 8K — 8 потоков
С маркерами,
интервал 10
Без маркеровОдин маркер на MCU,
интервал 1
2K, к/с38008694297
4K, к/с896255924
8K, к/с19746212

Декодер nvJPEG в этой части теста не показан: в многопоточном режиме с копированием его на этих файлах не тестировали.

Сколько рестарт-маркеры добавляют к размеру файлаПо сравнению с тем же потоком без маркеров, качество 90, 4:4:4
С маркерами,
интервал 10
Один маркер на MCU,
интервал 1
2K+ 2,1 %+ 21,2 %
4K+ 2,9 %+ 29,0 %
8K+ 2,9 %+ 29,0 %

Из этого следует главное, ради чего написана статья. Декодер Fastvideo JPEG быстр потому, что работает с изображениями, в которых есть маркеры: сегменты между ними он обрабатывает одновременно. Без маркеров параллельно декодировать нечего, и преимущество исчезает — это теперь не рассуждение, а измерение. Декодер nvJPEG работать с маркерами не умеет и обрабатывает поток последовательно в любом случае.

Поэтому кодер выбирают не только по скорости сжатия. Сжатое изображение когда-нибудь обязательно придётся декодировать — для обработки, для показа, для подачи в нейросеть, для работы с архивами сжатых изображений. Кодер, который вставляет маркеры, платит за это процентами размера файла один раз, а выигрыш есть каждый раз, когда изображение декодируют. Но это верно лишь при условии, что декодер умеет работать с маркерами.

2. Условия измерений

Стенд. Видеокарта NVIDIA RTX 4090, драйвер 610.88, процессор с 32 логическими ядрами, Windows 11. Fastvideo JPEG — из Fastvideo SDK 0.23.1.0, измерялся программой JpegSample из той же поставки. nvJPEG — из CUDA Toolkit, версия библиотеки 13.2.1.68, измерялся нашей программой nvjpeg_bench: она вызывает библиотеку напрямую, так, как её вызывал бы разработчик, а её исходный код выложен на GitHub вместе со скриптами тестирования (раздел 13). Оба кодека работают на вычислительных ядрах: аппаратного блока JPEG на этой карте нет, это проверено тремя независимыми способами.

Изображения. Три кадра: 2K, 1920×1080 пикселов, 4K, 3840×2160, и 8K, 7680×4320. Кадр 8K — это четыре копии кадра 4K, сложенные два на два. В разделе 5 — ещё два кадра, 12K, 11520×6480, и 16K, 15360×8640, сложенные так же, три на три и четыре на четыре; их делает скрипт make-big-frames-02.py из репозитория. Восемь бит на канал, три канала, прореживания нет — 4:4:4; только в разделе 4.1 те же кадры сжаты с прореживанием 4:2:0. Качество 90, то есть параметр качества q = 90. Базовый JPEG, особые режимы ни у одного из кодеков не включались.

Какое время измерялось. В разделах 1, 3, 4, 5 и 6 — только работа кодека на видеокарте. Кодер получает изображение, которое уже лежит в памяти видеокарты, и оставляет там же сжатый поток; декодер получает сжатый поток и оставляет в памяти видеокарты готовое изображение. Копирование между оперативной памятью и памятью видеокарты в это время не учитывается. В разделах 8 и 9 и в многопоточной части теста из раздела 1.1 копирование в обе стороны учтено.

Измерений два, потому что они отвечают на разные вопросы. Несжатое изображение копируется по PCIe целиком, и на кадрах 2K и 4K скорость ограничена именно пропускной способностью шины: при кодировании вместе с копированием оба кодека используют 83–93 % её пропускной способности. Такое измерение показывает возможности шины PCIe, а не кодека. Для оценки скорости процессов кодирования или декодирования не стоит включать в измерения время копирования. Чтобы узнать время выполнения всей задачи «взять изображение из оперативной памяти, сжать и вернуть», время копирования учитывать нужно. Смешивать эти результаты в одной таблице нельзя.

Потоки. В разделах 1, 3, 4, 5 и 6 работа идёт в один поток (кроме многопоточной части теста в разделе 1.1): тогда сравнение не зависит от того, как каждый кодек распараллелен снаружи. В разделах 7, 8 и 9 для каждого кодека выбран оптимальный набор параметров — тот, при котором его скорость наибольшая; перебирались три набора, от 8 до 32 потоков.

Повторы. Каждое измерение повторялось три раза, в таблицах — медиана. Перед каждым повтором скрипт проверял, не занята ли карта посторонней программой; во время измерений скорости и энергии она не была занята ни разу. Во всех измерениях, которые приведены в статье, повторы разошлись не больше чем на 7 %. Кадры 12K и 16K мерились отдельной серией и по более строгому порядку — он описан в разделе 5.

Когда. Тесты в статье проведены 25 сентября 2026 года, кадры 12K и 16K (раздел 5) — 29 сентября 2026 года, на том же стенде.

Одинаковую ли работу делают кодеки. У этих кодеков одинаковые исходные таблицы квантования, поэтому при одинаковом значении качества они дают практически одинаковые изображения после сжатия. Совпадение таблиц проверено на двенадцати парах: 2K, 4K и 8K, качество 80, 85, 90 и 95. Таблица квантования записана в самом файле JPEG, так что эту проверку может повторить кто угодно. PSNR при одинаковом качестве различается не больше чем на 0,1 дБ.

3. Скорость кодирования

В однопоточном режиме кодер Fastvideo быстрее на 30 % на кадре 2K, на 39 % на 4K и на 32 % на 8K. Эти результаты показаны и на первой картинке статьи.

Сравнение идёт не на равных, причём не в пользу кодера Fastvideo: он делает дополнительную работу, которой nvJPEG не делает, — вставляет рестарт-маркеры. Он быстрее не потому, что делает меньше.

От 2K к 4K объём данных растёт вчетверо, а время кадра у обоих кодеров — примерно вдвое: 5595 к/с против 2805 к/с у Fastvideo, 4313 к/с против 2014 к/с у nvJPEG. От 4K к 8K объём данных снова растёт вчетверо, и время кадра растёт уже почти во столько же раз — в 3,9 раза у Fastvideo и в 3,7 раза у nvJPEG. На какие стадии уходит время кадра при кодировании, здесь не измерялось.

Скорость кодирования JPEGОдин поток, качество 90, 4:4:4, без копирования на видеокарту и обратно
Fastvideo,
к/⁠с
nvJPEG,
к/⁠с
Fastvideo,
мс
nvJPEG,
мс
Разница
2K559543130,1790,232+ 30 %
4K280520140,3570,497+ 39 %
8K7155411,401,85+ 32 %

Время одного кадра в миллисекундах пересчитано из кадров в секунду. Оно приведено для того, чтобы время кодирования можно было складывать с временем других стадий обработки на видеокарте.

Собственная скорость кодера выше пропускной способности шины. Чтобы сравнить скорость кодера с пропускной способностью шины, будем считать её в гигабайтах в секунду относительно размера несжатых данных. В один поток кодер Fastvideo обрабатывает: 2K, q = 90, 4:4:4 — 35 ГБ/с; 4K, q = 90, 4:4:4 — 70 ГБ/с; 8K, q = 90, 4:4:4 — 71 ГБ/с; 8K, q = 90, 4:2:0 — 96 ГБ/с (раздел 4.1). Пропускная способность PCIe на этом стенде — 25,5 ГБ/с, то есть кодер работает в 1,4–3,8 раза быстрее, чем шина успевает подавать ему изображения. Поэтому скорость вместе с копированием (раздел 8) показывает возможности шины, а собственная скорость кодера видна там, где исходное изображение уже находится в памяти видеокарты: в конвейере обработки кадров с камеры, после декодирования, после других стадий обработки на видеокарте. Через шину тогда передаётся только сжатое изображение, а оно в несколько раз меньше исходного.

4. Скорость декодирования

Здесь, тоже в однопоточном режиме, разница уже не в процентах, а в разах, и она тем больше, чем крупнее изображение: в 9,7 раза на 2K, в 28 раз на 4K и в 35 раз на 8K.

Читать это надо так. Сравниваются не два декодера на одном и том же материале, а две связки «кодер плюс декодер», как они работают у пользователя: каждый декодер получает то изображение, которое сжал его собственный кодер. У Fastvideo в сжатых кадрах есть рестарт-маркеры, и сегменты декодируются одновременно на тысячах ядер. У nvJPEG маркеров нет, и декодирование идёт последовательно — в следующем разделе видно, где именно. Тест из раздела 1.1 показывает, что разница именно в маркерах: на файле без маркеров преимущества у декодера Fastvideo нет.

Поэтому и время кадра с ростом разрешения растёт у кодеков по-разному. От 2K к 4K у Fastvideo время кадра выросло всего на 14 % — с 0,537 до 0,610 мс; у nvJPEG в 3,2 раза — с 5,25 до 16,9 мс, вслед за ростом объёма данных. Так ведёт себя последовательное декодирование. От 4K к 8K время кадра у Fastvideo выросло уже в 3,2 раза, до 1,94 мс, у nvJPEG — в 4,0 раза, до 67,2 мс. Как время кадра растёт дальше, на кадрах 12K и 16K, — в разделе 5.

Скорость декодирования JPEGКаждый декодер работает с изображением своего кодера; один поток, качество 90, 4:4:4, без копирования на видеокарту и обратно
Fastvideo,
к/⁠с
nvJPEG,
к/⁠с
Fastvideo,
мс
nvJPEG,
мс
Разница
2K18621910,5375,25в 9,7 раза
4K164059,10,61016,9в 28 раз
8K51514,91,9467,2в 35 раз

4.1. Прореживание 4:2:0

При прореживании 4:2:0 в каждом цветоразностном канале вчетверо меньше пикселов, а всего данных вдвое меньше, и оба кодера сжимают быстрее. При декодировании картина расходится: декодер nvJPEG ускоряется на 55–64 %, а декодер Fastvideo на кадрах 2K и 4K, наоборот, замедляется на 17–25 %, и только на 8K ускоряется на 25 %. Разрыв между декодерами сокращается с 10 до 4,9 раза на кадре 2K, с 29 до 15 раз на 4K и с 38 до 29 раз на 8K.

Рядом с этим стоит наблюдение, которое мы пока не проверяли отдельно. При 4:2:0 блок MCU занимает 16×16 пикселов вместо 8×8, и рестарт-интервал кодера Fastvideo — 5 блоков MCU вместо 10. Сегментов в кадре от этого становится вдвое меньше: на 2K 1632 вместо 3240, на 4K 6480 вместо 12960, на 8K 25920 вместо 51840. Не доказано, что именно это замедляет декодер Fastvideo на 2K и 4K: это совпадение, а не измеренная причина. И объясняет оно не всё: на 8K сегментов тоже вдвое меньше, а декодер Fastvideo там не замедляется, а ускоряется.

Кодирование и декодирование при прореживании 4:4:4 и 4:2:0Один поток, качество 90, отдельная серия измерений
4:4:4,
к/⁠с
4:2:0,
к/⁠с
Изменение
Fastvideo, кодирование 2K53865508+ 2 %
Fastvideo, кодирование 4K28063734+ 33 %
Fastvideo, кодирование 8K716963+ 34 %
nvJPEG, кодирование 2K41934471+ 7 %
nvJPEG, кодирование 4K20142552+ 27 %
nvJPEG, кодирование 8K541749+ 38 %
Fastvideo, декодирование 2K18381379− 25 %
Fastvideo, декодирование 4K16391363− 17 %
Fastvideo, декодирование 8K527660+ 25 %
nvJPEG, декодирование 2K181280+ 55 %
nvJPEG, декодирование 4K55,689,2+ 60 %
nvJPEG, декодирование 8K13,722,4+ 64 %

Результаты для 4:4:4 измерены в той же серии, что и для 4:2:0, по очереди с ними, поэтому они немного отличаются от разделов 3 и 4. Строки 8K измерены отдельной серией в тот же день.

5. Бенчмарки больших разрешений: кадры 12K и 16K

Изображения крупнее 8K встречаются во многих задачах: их получают с камер высокого разрешения, например в аэрофотосъёмке, и сшивкой многих снимков — в панорамах улиц, цифровой патологии, спутниковой съёмке, микроскопии. Мы проверили, какую скорость дают кодеки на кадрах 12K и 16K.

Как сделаны кадры. Так же, как кадр 8K: из копий кадра 4K, положенных рядом. Кадр 12K — 11520×6480 пикселов (75 Мпикс), девять копий, три на три; кадр 16K — 15360×8640 пикселов (133 Мпикс), шестнадцать копий, четыре на четыре. Кадры делает скрипт make-big-frames-02.py из репозитория (раздел 13): сами кадры весят 224 и 398 МБ, а из кадра 4K любой может сделать их за несколько секунд. Условия те же, что в разделах 3, 4 и 4.1: q = 90, 4:4:4 и 4:2:0, изображения обрабатываются по одному, без копирования на видеокарту и обратно. Каждый декодер работает с изображением своего кодера.

Повторы. Кадры 12K и 16K мерились отдельной серией, на том же стенде. Каждое измерение повторялось не меньше трёх раз, и всё время замера скрипт раз в секунду записывал загрузку и мощность видеокарты. Если во время повтора видеокарта потребляла больше чем на 20 % сверх самого тихого повтора того же измерения, значит, на ней работала посторонняя программа: такой повтор в медиану не шёл, и делались дополнительные повторы. Таких повторов не было ни одного. В таблицах — медиана чистых повторов; они разошлись не больше чем на 7,6 %.

Сегментов в кадре становится больше вместе с размером кадра. Рестарт-интервал кодера Fastvideo — 10 блоков MCU при 4:4:4 и 5 при 4:2:0, поэтому кадр делится на сегменты так:

Число сегментов в кадре у кодера FastvideoЧисло блоков MCU, делённое на рестарт-интервал
Размер,
Мпикс
4:4:44:2:0
Кадр 8K3351 84025 920
Кадр 12K75116 64058 320
Кадр 16K133207 360103 680

У файлов nvJPEG маркеров нет, и весь кадр — один сегмент: кадр любого размера nvJPEG декодирует последовательно, выполняя энтропийное декодирование на процессоре.

Маркеры позволяют декодировать часть изображения. Каждый сегмент начинается с маркера и декодируется независимо от остальных, а сколько в нём блоков MCU, задано рестарт-интервалом. Поэтому по номеру сегмента можно вычислить, какой участок изображения он содержит: у кодера Fastvideo на кадрах этого раздела это полоса 80×8 пикселов при 4:4:4 и 80×16 при 4:2:0. Иначе говоря, маркеры делят изображение на небольшие участки с известными границами, по сути на плитки (тайлы), и найти их можно простым просмотром байтов. Тогда можно декодировать только те сегменты, которые попадают в нужную часть изображения, например в ту, что сейчас видна на экране, а остальные не трогать. Для сшитых изображений это может быть важнее скорости декодирования целиком: их обычно смотрят по частям. В файле без маркеров так нельзя: чтобы добраться до нужного места, приходится энтропийно декодировать всё, что идёт в потоке перед ним. В декодере Fastvideo такого режима сейчас нет, он обрабатывает изображение целиком, но формат это позволяет, и такой режим можно сделать под задачу, где он нужен.

Кодирование и декодирование кадров 8K, 12K и 16KОдин поток, q = 90, 4:4:4, без копирования на видеокарту и обратно
Fastvideo,
к/⁠с
nvJPEG,
к/⁠с
Fastvideo,
ГБ/⁠с
Разница
Кодирование 8K71554171+ 32 %
Кодирование 12K33524875+ 35 %
Кодирование 16K19113776+ 39 %
Декодирование 8K51514,951в 35 раз
Декодирование 12K2216,0549в 37 раз
Декодирование 16K1183,4347в 34 раза

ГБ/с — объём несжатых данных в секунду: кадры в секунду, умноженные на число пикселов и на три байта, как в разделе 8. Пропускная способность PCIe на этом стенде — 25,5 ГБ/с.

Кодирование. Кодер Fastvideo сжимает кадр 12K со скоростью 335 к/с, кадр 16K — 191 к/с, то есть 75 и 76 ГБ/с против 71 ГБ/с на кадре 8K. С прореживанием 4:2:0 — 102 и 104 ГБ/с. Это в 2,9–4,1 раза больше пропускной способности PCIe. Кодер Fastvideo быстрее кодера nvJPEG на 35 % на кадре 12K и на 39 % на 16K; на 8K разница была 32 %.

Декодирование. Декодер Fastvideo обрабатывает кадр 12K со скоростью 221 к/с, кадр 16K — 118 к/с, декодер nvJPEG — 6,05 и 3,43 к/с: декодер Fastvideo быстрее в 37 раз на кадре 12K и в 34 раза на 16K. У декодера Fastvideo это 49 и 47 ГБ/с против 51 ГБ/с на кадре 8K. Декодер nvJPEG тратит на мегапиксел 2,02 мс на кадре 8K, 2,21 и 2,20 мс на 12K и 16K.

Прореживание 4:2:0. Как и в разделе 4.1, это дополнение к основным измерениям: те же кадры сжаты с прореживанием 4:2:0, и 4:4:4 измерено в той же серии, по очереди с ним. Оба кодера с прореживанием сжимают быстрее: кодер Fastvideo — на 36 и 37 %, кодер nvJPEG — на 45 и 49 %. Декодер Fastvideo ускоряется на 33 и 40 % — как на кадре 8K, а не как на 2K и 4K; декодер nvJPEG — на 65 % на обоих кадрах.

Кадры 12K и 16K при прореживании 4:4:4 и 4:2:0Один поток, q = 90, отдельная серия измерений
4:4:4,
к/⁠с
4:2:0,
к/⁠с
Изменение
Fastvideo, кодирование 12K335457+ 36 %
Fastvideo, кодирование 16K191261+ 37 %
nvJPEG, кодирование 12K248360+ 45 %
nvJPEG, кодирование 16K137204+ 49 %
Fastvideo, декодирование 12K221295+ 33 %
Fastvideo, декодирование 16K118165+ 40 %
nvJPEG, декодирование 12K6,0510,0+ 65 %
nvJPEG, декодирование 16K3,435,67+ 65 %

Аэрофотосъёмка. Кадры камер для аэрофотосъёмки — того же порядка: 100 Мпикс и больше (в настоящее время до 254 Мпикс). Если после преобразования RAW в RGB их сжимает кодер Fastvideo, маркеры в них уже есть, и специально готовить файлы не нужно. Кадр 16K — это 133 Мпикс: кодер Fastvideo сжимает его за 5,24 мс, декодер Fastvideo обрабатывает его за 8,47 мс, а декодеру nvJPEG на тот же кадр нужно 292 мс. JPEG в аэрофотосъёмке, с кадрами настоящих камер, мы подробно разберём в отдельной статье.

Что из этого следует. На крупных кадрах у кодека Fastvideo быстрее и кодирование, и декодирование: на кадре 16K кодер быстрее на 39 %, декодер — в 34 раза. Производительность кодека Fastvideo выходит на насыщение уже на кадре 8K. Поэтому обрабатывать несколько крупных кадров одновременно смысла нет.

6. Где теряет время декодер nvJPEG

График: доли стадий в полном времени кадра при декодировании nvJPEG — разбор потока и энтропийное декодирование на процессоре занимают 92 процента на кадре 2K, 93 процента на 4K и 91 процент на 8K
Штриховкой отмечена стадия, которая выполняется на центральном процессоре. На саму видеокарту приходится от 0,7 до 1,9 % времени кадра.

Декодирование у библиотеки nvJPEG разбито на три вызова: первый работает на процессоре, второй передаёт данные на видеокарту, третий работает на видеокарте. Наша программа для nvJPEG замеряет время каждого вызова отдельно и между вызовами ждёт, пока видеокарта закончит работу, поэтому видно, какая часть времени кадра приходится на каждую стадию. Разбор потока и энтропийное декодирование выполняются на центральном процессоре и последовательно: на них уходит 92 % времени на кадре 2K, 93 % на 4K и 91 % на 8K. На видеокарту приходится от 0,7 до 1,9 % — она почти всё это время не занята.

Это и есть цена отсутствия маркеров. Разделить сжатые данные на сегменты нечем, значит, и распараллелить нечего. Поэтому nvJPEG выполняет энтропийное декодирование на процессоре, последовательно.

Декодер nvJPEG работает следующим образом. Сначала процессор разбирает сжатые данные и выполняет энтропийное декодирование. Затем он передаёт полученные результаты на видеокарту. На видеокарте выполняется всё остальное: обратное квантование, обратное дискретное косинусное преобразование и переход из YCbCr в RGB.

Профилировщик подтверждает эту картину со стороны: у декодера nvJPEG на видеокарте работают всего два ядра — одно делает обратное квантование вместе с обратным косинусным преобразованием, другое делает обратное цветовое преобразование, — а ядра энтропийного декодирования нет ни одного. Подробнее об этом написано в разделе 7.

Доли стадий в полном времени кадра при декодировании nvJPEGВремя каждого из трёх вызовов декодера nvJPEG, замер нашей программы, один поток, качество 90, 4:4:4
Где работаетКадр 2KКадр 4KКадр 8K
разбор потока и энтропийное декодированиепроцессор91,9 %93,3 %91,4 %
передача данных с процессора на видеокартуPCIe7,4 %5,8 %6,7 %
обратное квантование, обратное косинусное преобразование, обратное цветовое преобразованиевидеокарта0,7 %0,9 %1,9 %

6.1. Режим пачки у nvJPEG: когда энтропийное декодирование переходит на видеокарту

График: скорость декодирования nvJPEG в зависимости от числа кадров в пачке, резкий рост между 32 и 64 кадрами
Пачка от одного до 128 кадров, кадр 2K, качество 90, 4:4:4. До 32 кадров в пачке скорость остаётся ниже 160 к/с, между 32 и 64 она вырастает в 2,7 раза.

У библиотеки nvJPEG есть свой способ обойти эту трудность — режим пачки: декодеру дают сразу много кадров за один вызов (функция nvjpegDecodeBatched). Такой режим есть только у декодирования; кодер nvjpegEncodeImage всегда обрабатывает один кадр за вызов.

Пока в пачке 50 кадров или меньше, энтропийное декодирование по-прежнему выполняется на процессоре, и пачка почти ничего не даёт: один кадр декодируется со скоростью 138 к/с (это отдельное измерение через функцию пачки; обычный вызов в разделе 4 даёт 191 к/с), пачка 32 кадра — 155 к/с. Когда кадров в пачке больше 50, nvJPEG переносит энтропийное декодирование на видеокарту. Внутри одного кадра делить поток по-прежнему не на что, но кадры в пачке друг от друга не зависят, и видеокарта декодирует их одновременно, каждый на своих ядрах. Скорость сразу растёт: 422 к/с при пачке 64 кадра и 742 к/с при пачке 128 кадров.

Число 50 — не наша оценка: так написано в документации к библиотеке, в её заголовочном файле nvjpeg.h, и результаты тестов с этим сходятся — скачок скорости приходится как раз между 32 и 64 кадрами.

Переход энтропийного декодирования на видеокарту здесь не предположение: в записи профилировщика при пачке 128 кадров появляется ядро decodeDcHuffman, которого при пачке 32 кадра нет, и на него приходится 95 % всего времени ядер (раздел 7).

Это лучший результат, который nvJPEG показывает при декодировании, но всё равно это значительно меньше, чем 1862 к/с у Fastvideo на одиночном изображении. Кроме того, за режим пачки приходится платить задержкой: 128 кадров надо сначала накопить. Поэтому режим пачки подходит там, где нужна наибольшая скорость, а задержка не важна. Главное такое применение — загрузка изображений JPEG при обучении нейросетей: на него рассчитана библиотека NVIDIA DALI, которая готовит данные для обучения и декодирует JPEG через nvJPEG. Другой пример — обработка готовых архивов и больших наборов снимков, где кадры уже лежат на диске.

Декодирование nvJPEG в режиме пачкиКадр 2K, качество 90, 4:4:4
Кадров
в пачке
13264128
Кадров в секунду138155422742
Где идёт энтропийное декодированиепроцессорпроцессорвидеокартавидеокарта

7. Что на самом деле делает видеокарта

Все измерения выше сделаны по системным часам. Часы говорят, сколько заняла работа целиком, но не говорят, чем в это время была занята видеокарта. Это показывает профилировщик: он записывает каждый запуск вычислительного ядра и каждое копирование с точностью до наносекунд. Измерения ниже сняты программой Nsight Systems на том же стенде, на кадре 2K, при оптимальном наборе параметров каждого кодека; ни один из кодеков ради этого не менялся.

Величины три. Время ядер на кадр — сколько видеокарта действительно вычисляла, без копирования и без ожидания. Доля времени вычислений — сколько времени на карте работало хоть одно вычислительное ядро. Доля простоя — сколько времени карта не делала ничего: ни вычислений, ни копирования.

Работа видеокарты при декодированииКадр 2K, качество 90, 4:4:4, оптимальный набор параметров каждого кодека
Время ядер
на кадр, мс
Доля времени
вычислений
Доля простоя
Fastvideo JPEG, 32 потока0,43359 %6,6 %
nvJPEG, 8 потоков по 2 изображения0,0273,1 %2,5 %

По времени вычислений на видеокарте разница — в 16 раз. Это не скорость, а объём работы, который каждый кодек отдаёт видеокарте. У декодера Fastvideo на карте выполняется весь алгоритм, включая энтропийное декодирование; у nvJPEG — только обратное квантование, обратное косинусное преобразование и обратное цветовое преобразование.

Простоя у nvJPEG при этом почти нет, 2,5 %. Карта не бездействует: почти всё остальное время на ней идёт копирование — пока один поток ждёт процессор, другой передаёт данные на видеокарту или забирает готовое изображение. Вычисляет при этом карта 3 % времени.

Имена ядер показывают, что именно вычисляет видеокарта. Профилировщик записывает имя каждого ядра, а имена здесь говорят сами за себя.

Ядра, на которые приходится основное времяКадр 2K, качество 90, 4:4:4
Ядра и их доля во времени ядер
Fastvideo, декодированиеHuffmanDecodeKernel 71 %, RleDecodeKernel 12 %, InverseDCTColorKernel 5,1 %
nvJPEG, декодированиеdctQuantInvJpegKernelMultiChannel 74 %, ycbcr_to_format_kernel_roi 26 % — и больше ничего
Fastvideo, кодированиеRleBalancedKernel 30 %, DCT444Kernel 19 %, applyImageProcessingColor_8 17 %, HuffmanAndStuffingKernel 17 %
nvJPEG, кодированиеACKernel 37 %, format_to_ycbcr_kernel 15 %, forwardDct32x8Kernel 13 %, DCKernel 10 %

У декодера nvJPEG в списке два ядра, и оба относятся к тому, что идёт после энтропийного декодирования. Энтропийного декодирования в записи профилировщика нет, потому что на видеокарте его и не происходит. У декодера Fastvideo первое же ядро — HuffmanDecodeKernel, и на него приходится почти три четверти времени вычислений.

У кодеров картина другая, и это подтверждает сказанное в разделе 1. У nvJPEG при кодировании работают ACKernel и DCKernel — кодирование коэффициентов AC и DC, то есть та самая энтропийная стадия. Она у него на видеокарте, и маркеры ей не нужны: при кодировании границы блоков известны заранее. Кодер Fastvideo, как и декодер, выполняет энтропийную стадию на видеокарте: ядра RleBalancedKernel и HuffmanAndStuffingKernel — это кодирование длин серий и кодирование по Хаффману, и на них приходится почти половина времени ядер.

7.1. Режим пачки у nvJPEG под профилировщиком

В разделе 6.1 видно, что между пачкой 32 кадра и пачкой 128 кадров скорость скачком вырастает. Профилировщик показывает, из чего этот скачок состоит.

Режим пачки у nvJPEG под профилировщикомКадр 2K, качество 90, 4:4:4
Пачка 32 кадраПачка 128 кадров
Время ядер на кадр, мс0,1221,08
Доля времени вычислений2,0 %79 %
Доля простоя76 %1,4 %
Ядро энтропийного декодированиянетdecodeDcHuffman,
95 % времени ядер

При пачке 32 кадра видеокарта три четверти времени простаивает: она ждёт, пока процессор разберёт сжатые данные. При пачке 128 кадров энтропийное декодирование перешло на видеокарту, простоя почти нет, а время работы ядер на кадр увеличилось почти в девять раз. Ускорение приходит не оттого, что видеокарта стала быстрее вычислять, а оттого, что у неё появилась работа, которую можно разделить между ядрами. С маркерами между ядрами делится один кадр, в режиме пачки — сто двадцать восемь разных кадров.

Чего эти измерения не показывают. Профилировщик видит только видеокарту: сколько времени и на что тратит центральный процессор, он не показывает. В многопоточном режиме ядра разных потоков работают одновременно, поэтому время ядер нельзя складывать с временем кадра из разделов 3 и 4: это разные величины.

8. Скорость вместе с копированием на видеокарту и обратно

График: наибольшая скорость кодирования и декодирования JPEG на RTX 4090 в многопоточном режиме вместе с копированием на видеокарту и обратно, Fastvideo JPEG и nvJPEG на кадрах 2K, 4K и 8K
Наибольшая скорость, которую каждый кодек даёт на RTX 4090: оптимальный набор параметров, вместе с копированием на видеокарту и обратно. Скорость кодирования ограничена пропускной способностью шины PCIe, поэтому на 2K кодеки вровень, а на 4K и 8K nvJPEG быстрее; при декодировании разница остаётся.

Второе измерение: изображение лежит в оперативной памяти, копируется в память видеокарты, обрабатывается и возвращается обратно. Несжатое изображение копируется по PCIe целиком, сжатое — тоже, но оно в несколько раз меньше. Пропускная способность шины на этом стенде 25,5 ГБ/с, её измерили сами программы. Для каждого кодека выбран оптимальный набор параметров из трёх, от 8 до 32 потоков.

Почему наибольшая скорость измерена только вместе с копированием. В многопоточном режиме программа JpegSample измеряет время обработки целиком, вместе с копированием в память видеокарты и обратно, а время работы самого кодека отдельно не показывает. Поэтому многопоточного сравнения без копирования в статье нет: у nvJPEG его измерить можно, а у Fastvideo JPEG — нет, и такое сравнение было бы неравным.

При кодировании вместе с копированием скорость у обоих кодеков ограничена шиной. На кадрах 2K и 4K они используют 83–93 % её пропускной способности, и разница между ними в том, насколько плотно каждый загружает шину, а не в скорости вычислений: на 2K кодеки вровень, на 4K nvJPEG быстрее на 12 %, потому что использует 93 % пропускной способности против 83 % у Fastvideo. Быстрее, чем данные копируются по PCIe, работать не получится.

На кадре 8K кодер nvJPEG быстрее на 22 %: 235 к/с против 192. Он использует 92 % пропускной способности шины, Fastvideo — 75 %. Оптимальный набор параметров Fastvideo на 8K — 8 потоков по два кадра, и шину он загружает не полностью; с бо́льшим числом потоков скорость на кадре такого размера уже не растёт.

При декодировании пропускная способность шины ограничивает только Fastvideo. Он использует 87–89 % её пропускной способности на кадрах 2K и 4K и 75 % на 8K, nvJPEG — около четверти. Скорость nvJPEG ограничена работой на процессоре, а не шиной, поэтому разница между кодеками видна и в этом измерении.

Почему здесь разница в 3 раза, а в разделах 4 и 5 — в десятки раз. Там кодеки работают в один поток и без копирования: на кадре 8K декодер Fastvideo обрабатывает 515 к/с, декодер nvJPEG — 14,9 к/с, в 35 раз меньше. Здесь меняются обе стороны. Декодер Fastvideo упирается в шину: 193 к/с, 75 % её пропускной способности. Декодер nvJPEG в восьми потоках ведёт энтропийное декодирование нескольких кадров одновременно на разных ядрах процессора — занято около шести ядер — и даёт 65 к/с вместо 14,9. Разница в 35 раз — это скорость самих декодеров, разница в 3 раза — скорость всей обработки вместе с копированием по шине на этом компьютере.

Скорость вместе с копированием на видеокарту и обратноОптимальный набор параметров каждого кодека, качество 90, 4:4:4; в скобках — доля пропускной способности шины
Fastvideo,
к/⁠с
nvJPEG,
к/⁠с
Fastvideo,
ГБ/⁠с (доля)
nvJPEG,
ГБ/⁠с (доля)
Кодирование 2K3497353221,8 (85 %)22,0 (86 %)
Кодирование 4K84895121,1 (83 %)23,7 (93 %)
Кодирование 8K19223519,1 (75 %)23,4 (92 %)
Декодирование 2K3632116122,6 (89 %)7,2 (28 %)
Декодирование 4K89526822,3 (87 %)6,7 (26 %)
Декодирование 8K1936519,2 (75 %)6,5 (25 %)

Гигабайты в секунду в этой таблице — объём несжатых данных в секунду: кадры в секунду, умноженные на число пикселов и на три байта. В скобках — какую долю пропускной способности шины использует кодек; она считается от измеренных 25,5 ГБ/с.

9. Потребление энергии видеокартой

График: потребление энергии видеокартой на один кадр при кодировании JPEG на RTX 4090, в джоулях, у Fastvideo JPEG и nvJPEG — у Fastvideo меньше в 1,1–1,3 раза
Джоули на один кадр при кодировании по счётчику видеокарты, качество 90, 4:4:4, оптимальный набор параметров, вместе с копированием. Здесь учтено только потребление энергии видеокартой; энергию процессора этот счётчик не видит.

Энергия измерена в тех же условиях, что и скорость в разделе 8: вместе с копированием на видеокарту и обратно, и у каждого кодека — при оптимальном наборе параметров. Измерена она счётчиком самой видеокарты. Он считает всю энергию, которую потребляет карта: на вычисления, на копирование, на память и на собственное потребление в простое. Программу запускают дважды, на N и на 2N кадров, и энергия кадра — разность двух показаний счётчика, делённая на N: так из результата уходят затраты на запуск программы, которые от числа кадров не зависят. Потребление в простое при этом в результате остаётся — карта потребляет эту мощность всё время, пока идёт обработка, в том числе пока она ждёт процессор. В простое эта карта потребляет от 45 до 76 Вт (в разных измерениях) при пределе 450 Вт. Проверка другим способом — средняя мощность карты, умноженная на время кадра, — дала те же результаты с точностью до 9 %.

По энергии кодеки сравниваются только на кодировании: и у Fastvideo, и у nvJPEG оно целиком идёт на видеокарте, и счётчик видит всю работу. На кодирование одного кадра видеокарта с кодеком Fastvideo тратит в 1,1–1,3 раза меньше энергии, хотя по скорости кодирования с копированием кодеки близки, а на 4K и 8K nvJPEG даже быстрее: скорость ограничивает пропускная способность шины (раздел 8).

Почему у декодера nvJPEG прочерк. Большую часть времени кадра этот декодер работает на центральном процессоре — там идут разбор сжатого потока и энтропийное декодирование (раздел 6), — а видеокарта в это время ждёт. Счётчик видеокарты показывает для него в основном то, что карта потребляет, пока ждёт процессор (в среднем 92–96 Вт), а не работу декодера, энергию же самого процессора он не видит. Такой результат с результатом декодера Fastvideo сравнивать нельзя, поэтому в таблице прочерк. Декодер Fastvideo работает на видеокарте целиком, включая энтропийное декодирование: маркеры делят поток на сегменты. Поэтому его энергия на кадр в таблице есть.

Потребление энергии видеокартой на один кадрПо счётчику видеокарты, оптимальный набор параметров, вместе с копированием, качество 90, 4:4:4
Fastvideo,
Дж
nvJPEG,
Дж
Разница
Кодирование 2K0,0440,055в 1,3 раза
Кодирование 4K0,170,19в 1,1 раза
Кодирование 8K0,720,78в 1,1 раза
Декодирование 2K0,056——
Декодирование 4K0,17——
Декодирование 8K0,71——

10. Как этим пользоваться

Из измерений следует несколько правил, и все они про то, что решение принимается при кодировании, а расплата или выигрыш приходят при декодировании.

Кодер выбирают не только по скорости сжатия. В однопоточном режиме разница в скорости кодирования — 30–39 %, а разница при декодировании того, что этот кодер сжал, — в 9,7 раза на кадре 2K, в 28 раз на 4K и в 35 раз на 8K. Изображение сжимают один раз, а декодируют всякий раз, когда к нему обращаются.

Рестарт-маркеры стоят 2,1–2,9 % размера файла. Время, которое кодер тратит на их вставку, уже входит в его скорость, и кодер Fastvideo при этом быстрее nvJPEG. Совместимость они не нарушают: маркеры входят в стандарт, и программа, которая не умеет с ними работать, читает такой файл как обычный.

Если кадры приходят пачками и задержка не важна, у nvJPEG есть режим пачки: начиная с 64 кадров в пачке энтропийное декодирование у него выполняется на видеокарте, и скорость поднимается до 742 к/с.

Если задача сводится к тому, чтобы взять изображение из оперативной памяти, сжать и вернуть, скорость будет зависеть от пропускной способности шины PCIe, а не от кодека: при сжатии кадров 2K и 4K оба используют 83–93 % пропускной способности шины. Сам кодер при этом работает с большим запасом: на кадре 8K, q = 90, 4:2:0 кодер Fastvideo обрабатывает 96 ГБ/с, в 3,8 раза больше пропускной способности шины. Выигрыш в скорости кодека виден там, где изображение попадает в память видеокарты один раз, а стадий обработки над ним много, и их время складывается.

10.1. На каких изображениях декодер Fastvideo работает быстро

Высокая скорость декодирования, показанная в этой статье, возможна только на изображениях с рестарт-маркерами. Таких изображений два вида:

Самая высокая скорость — только на специально подготовленных изображениях. С маркером после каждого блока MCU декодер Fastvideo работает ещё быстрее: 3296 к/с на кадре 2K вместо 1864, 2035 к/с на 4K вместо 1652 и 650 к/с на 8K вместо 527 (раздел 1.1). В руководстве к Fastvideo SDK рестарт-интервал 1 и назван оптимальным для декодера. Кодер Fastvideo таких файлов не делает: его рестарт-интервал — 10 блоков MCU, а не 1. Такие файлы готовят заранее другой программой, например jpegtran, и платят за это размером: файл становится на 21–29 % больше, чем без маркеров.

На изображениях без маркеров такой высокой скорости получить нельзя. Без рестарт-маркеров декодер Fastvideo выполняет энтропийное декодирование на центральном процессоре. Маркеры не вставляет и nvJPEG, а libjpeg-turbo вставляет их только по отдельному ключу, так что многие файлы JPEG, которые приходят со стороны, их не содержат. Такие изображения можно декодировать только последовательно, и преимущества у декодера Fastvideo на них нет (раздел 1.1). Это не свойство конкретной библиотеки, а свойство сжатого изображения: если маркеров нет, то и быстрого декодирования на видеокарте для таких изображений не получится.

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

11. Заключение

На RTX 4090 в однопоточном режиме кодер Fastvideo JPEG сжимает изображения 2K, 4K и 8K на 30–39 % быстрее библиотеки nvJPEG. Это заметная, но не главная разница. Главное в том, что он при этом вставляет в поток рестарт-маркеры, которых nvJPEG не вставляет никогда, и платит за них 2,1–2,9 % размера файла.

При декодировании разница между кодеками гораздо больше: декодер Fastvideo быстрее декодера nvJPEG в 9,7 раза на кадре 2K, в 28 раз на 4K и в 35 раз на 8K (каждый обрабатывает файлы своего кодера, однопоточный режим). Причина — рестарт-маркеры. Они делят сжатые данные на сегменты, и видеокарта декодирует их одновременно. В файлах кодера Fastvideo маркеры есть, в файлах nvJPEG их нет. Декодер nvJPEG выполняет энтропийное декодирование на центральном процессоре, даже если маркеры в файле есть; на энтропийное декодирование у него уходит 91–93 % времени кадра. Даже в режиме пачки, где энтропийное декодирование у nvJPEG идёт на видеокарте, он обрабатывает кадр 2K в лучшем случае со скоростью 742 к/с — в 2,5 раза медленнее декодера Fastvideo (1862 к/с).

Большие разрешения. На кадрах 12K и 16K кодер Fastvideo быстрее кодера nvJPEG на 35 и 39 %, а декодер Fastvideo быстрее декодера nvJPEG в 37 раз на кадре 12K и в 34 раза на 16K (раздел 5). Производительность кодека Fastvideo выходит на насыщение уже на кадре 8K. Поэтому обрабатывать несколько крупных кадров одновременно смысла нет.

С прореживанием 4:2:0 декодер Fastvideo тоже быстрее декодера nvJPEG: в 4,9 раза на кадре 2K, в 15 раз на 4K и в 29 раз на 8K (раздел 4.1). В многопоточном режиме вместе с копированием на видеокарту и обратно декодер Fastvideo быстрее в 3,0–3,3 раза. Кодеры в этом режиме на кадре 2K идут почти вровень, а на 4K и 8K кодер nvJPEG быстрее — на 12 и 22 % (раздел 8). При кодировании видеокарта с кодеком Fastvideo тратит на кадр в 1,1–1,3 раза меньше энергии. Декодеры по энергии не сравнивались: у nvJPEG большая часть работы идёт на процессоре, а его энергию счётчик видеокарты не видит.

Что из этого следует при выборе кодека. Одной скорости сжатия для выбора мало: важно ещё, сколько раз изображение потом будут декодировать. Скорость декодирования определяется уже при сжатии. Если в изображении есть рестарт-маркеры, его можно декодировать на видеокарте параллельно и быстро; если маркеров нет, декодирование будет последовательным, каким бы ни был декодер.

12. Что в этих измерениях не проверялось

13. Что почитать по теме

Всё для повторения измерений — на GitHub: github.com/fastvideo/jpeg-benchmark. Там скрипты тестирования, исходный код нашей программы для nvJPEG, сводки и логи всех измерений 25 и 29 сентября 2026 года и описание, как повторить их на своей машине. Программы JpegSample в репозитории нет: она входит в Fastvideo SDK.

Обе реализации доступны: кодек Fastvideo JPEG входит в Fastvideo SDK вместе с программой JpegSample, библиотека nvJPEG — в CUDA Toolkit, и рядом с ней лежат примеры NVIDIA. Чтобы проверить скорость на своих изображениях, запросите Fastvideo SDK — пришлём сборку для Windows, Linux или ARM.

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

Текст статьи — под лицензией CC BY-ND 4.0: перепечатывать целиком и цитировать можно, в том числе в коммерческих изданиях, со ссылкой на источник; переводить и перерабатывать можно с нашего письменного разрешения — напишите нам через форму внизу страницы.

Результаты измерений и таблицы — под лицензией CC BY 4.0: их можно переносить в свои материалы, пересобирать и считать на их основе. Если что-то изменили — скажите, что именно.

Ссылка на источник в обоих случаях: Fastvideo, <адрес статьи>, измерения от 25.09.2026 и 29.09.2026. Просьба приводить условия измерений рядом с результатами: без них результат не воспроизводится.

На изображения ни одна из этих лицензий не распространяется.

Фёдор Серженко, основатель Fastvideo, автор статьи

Об авторе

Фёдор Серженко, к.ф.-м.н. — основатель и генеральный директор Фаствидео. Кандидатскую защитил в МФТИ в 1993 году. С 2009 года ведёт разработку кодеков и модулей обработки изображений на видеокартах, включая Fastvideo SDK. Профиль в LinkedIn.

Почему этим результатам можно верить

Фаствидео делает обработку изображений на видеокартах с 2009 года. Кодек JPEG соответствует стандарту, который реализует, — ITU-T T.81 / ISO IEC 10918. Любой опубликованный результат воспроизводим: скрипты этих измерений, наша программа для nvJPEG и сырые логи лежат в открытом репозитории, демонстрационные версии — в разделе загрузок.

Читайте также

Декодирование больших JPEG на видеокарте: аэрофотоснимки 50–150 Мпикс, рестарт-маркеры Большие JPEG на видеокарте: аэрофотоснимки 50–150 Мпикс Сравнение кодеков JPEG2000 на видеокарте RTX 4090: кодек из Fastvideo SDK и библиотека nvJPEG2000 JPEG2000 на GPU: кодек из Fastvideo SDK и библиотека nvJPEG2000 Сравнение Fastvideo SDK и библиотеки NVIDIA NPP для обработки изображений на видеокарте Сравним Fastvideo SDK и NVIDIA NPP

Форма для отправки запроса

Эта форма сохраняет ваше имя и адрес электронной почты.