Бенчмарки кодеков 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 маркеры не вставляет и работать с ними не умеет. Поэтому от выбора кодека зависит не только скорость кодирования, но и скорость декодирования, причём наибольшее влияние этот выбор оказывает именно на декодирование.

Эта статья есть и в виде PDF: Бенчмарки кодеков Fastvideo JPEG и NVIDIA nvJPEG на RTX 4090 (технический отчёт) — тот же текст, числа и графики, с оглавлением и номерами страниц, чтобы читать без сети и передавать дальше.
Главные результаты
RTX 4090, Fastvideo SDK 0.23.1.0 и nvJPEG 13.2.1.68. Скорость — в кадрах в секунду (к/с). Условия — стандартные для измерений этой статьи (раздел 2), если в пункте не сказано иное.
| Тестовые кадры | Кодер Fastvideo | Кодер nvJPEG | Декодер Fastvideo | Декодер nvJPEG |
|---|---|---|---|---|
| 2K, 1920×1080 | 5595 к/с | 4313 к/с | 1862 к/с | 191 к/с |
| 4K, 3840×2160 | 2805 к/с | 2014 к/с | 1640 к/с | 59,1 к/с |
| 8K, 7680×4320 | 715 к/с | 541 к/с | 515 к/с | 14,9 к/с |
| 12K, 11520×6480 | 335 к/с | 248 к/с | 221 к/с | 6,05 к/с |
| 16K, 15360×8640 | 191 к/с | 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. Рассмотрим эту часть стандарта более подробно, эти термины нам пригодятся для понимания принципов работы кодека (в скобках — номера пунктов стандарта).
- Блок данных (data unit, п. 3.1.34) — блок 8×8: квадрат 8×8 значений одной компоненты изображения: яркости Y или одной из цветоразностных компонент Cb и Cr. Над ним выполняются косинусное преобразование и квантование. В блоке 64 коэффициента: один коэффициент DC — среднее значение по блоку — и 63 коэффициента AC.
- Энтропийное кодирование — последняя стадия сжатия, это кодирование без потерь. Коэффициенты блока после квантования кодируются по-разному. Коэффициенты DC сжимаются с помощью дельта-кодирования: записывается не абсолютная величина, а разность с коэффициентом DC предыдущего блока той же компоненты. Коэффициенты AC идут по зигзагу, от низких частот к высоким; большинство из них после квантования становятся нулями, поэтому сначала серии нулей кодируются с помощью алгоритма кодирования длин серий (RLE), а затем полученные значения кодируются кодами Хаффмана переменной длины. Энтропийное декодирование выполняет всё это в обратном порядке. Дальше в статье речь идёт именно об этой стадии целиком, а не только о кодах Хаффмана.
- Блок MCU (minimum coded unit, п. 3.1.88) — наименьшая группа блоков данных, которая кодируется вместе. Из каких блоков он состоит, задают множители дискретизации компонент, записанные в заголовке кадра (п. A.2.3): компонента с множителями H×V даёт в блок MCU H×V блоков данных. При 4:4:4 блок MCU — это 8×8 пикселов и 3 блока данных, по одному на компоненту; при 4:2:0 — 16×16 пикселов и 6 блоков данных: 4 блока яркости и по одному блоку каждой цветоразностной компоненты.
- Скан (scan, п. 3.1.114) — один проход по данным изображения. В обычном JPEG все три компоненты идут в одном скане последовательно, блок MCU за блоком MCU, так что скан — это всё сжатое изображение целиком.
- Рестарт-интервал (restart interval, п. 3.1.109) — заданное число блоков MCU, которое кодируется как независимая последовательность внутри скана. Его значение записано в заголовке файла, в маркере DRI.
- Рестарт-маркер (restart marker, п. 3.1.110) — два байта, от
FFD0доFFD7, которые кодер вставляет в скан между рестарт-интервалами. - Энтропийно-кодированный сегмент (entropy-coded segment, п. 3.1.51) — сжатые данные одного рестарт-интервала. Стандарт определяет его как последовательность байтов, которую можно декодировать независимо от остальных. Дальше в статье — просто сегмент.
Как кодируются данные после рестарт-маркера. Коэффициент 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.
| Блок MCU, пикселов | Блоков 8×8 в блоке MCU | Интервал, блоков MCU | Блоков 8×8 в сегменте | |
|---|---|---|---|---|
| 4:4:4 | 8×8 | 3 | 10 | 30 |
| 4:2:2 | 16×8 | 4 | 8 | 32 |
| 4:2:0 | 16×16 | 6 | 5 | 30 |
| Монохромное | 8×8 | 1 | 32 | 32 |
Про 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. Одно и то же изображение с маркерами и без них: результаты теста

Чтобы роль маркеров была не догадкой, а результатом теста, мы измерили её прямо. Изображение, сжатое кодером 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 % медленнее: маркеров больше, и каждый приходится пропускать.
| Fastvideo, к/с | nvJPEG, к/с | Fastvideo, мс | nvJPEG, мс | |
|---|---|---|---|---|
| 2K, с маркерами | 1864 | 174 | 0,536 | 5,74 |
| 2K, без маркеров | 96 | 177 | 10,4 | 5,64 |
| 2K, один маркер на MCU | 3296 | 161 | 0,303 | 6,21 |
| 4K, с маркерами | 1652 | 52,7 | 0,605 | 19,0 |
| 4K, без маркеров | 31 | 55,9 | 32,3 | 17,9 |
| 4K, один маркер на MCU | 2035 | 49,2 | 0,491 | 20,3 |
| 8K, с маркерами | 527 | 14,5 | 1,90 | 69,0 |
| 8K, без маркеров | 7 | 14,8 | 143 | 67,8 |
| 8K, один маркер на MCU | 650 | 12,5 | 1,54 | 79,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 потоков: кадру такого размера больше не нужно.
| С маркерами, интервал 10 | Без маркеров | Один маркер на MCU, интервал 1 | |
|---|---|---|---|
| 2K, к/с | 3800 | 869 | 4297 |
| 4K, к/с | 896 | 255 | 924 |
| 8K, к/с | 197 | 46 | 212 |
Декодер nvJPEG в этой части теста не показан: в многопоточном режиме с копированием его на этих файлах не тестировали.
| С маркерами, интервал 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. На какие стадии уходит время кадра при кодировании, здесь не измерялось.
| Fastvideo, к/с | nvJPEG, к/с | Fastvideo, мс | nvJPEG, мс | Разница | |
|---|---|---|---|---|---|
| 2K | 5595 | 4313 | 0,179 | 0,232 | + 30 % |
| 4K | 2805 | 2014 | 0,357 | 0,497 | + 39 % |
| 8K | 715 | 541 | 1,40 | 1,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.
| Fastvideo, к/с | nvJPEG, к/с | Fastvideo, мс | nvJPEG, мс | Разница | |
|---|---|---|---|---|---|
| 2K | 1862 | 191 | 0,537 | 5,25 | в 9,7 раза |
| 4K | 1640 | 59,1 | 0,610 | 16,9 | в 28 раз |
| 8K | 515 | 14,9 | 1,94 | 67,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, к/с | Изменение | |
|---|---|---|---|
| Fastvideo, кодирование 2K | 5386 | 5508 | + 2 % |
| Fastvideo, кодирование 4K | 2806 | 3734 | + 33 % |
| Fastvideo, кодирование 8K | 716 | 963 | + 34 % |
| nvJPEG, кодирование 2K | 4193 | 4471 | + 7 % |
| nvJPEG, кодирование 4K | 2014 | 2552 | + 27 % |
| nvJPEG, кодирование 8K | 541 | 749 | + 38 % |
| Fastvideo, декодирование 2K | 1838 | 1379 | − 25 % |
| Fastvideo, декодирование 4K | 1639 | 1363 | − 17 % |
| Fastvideo, декодирование 8K | 527 | 660 | + 25 % |
| nvJPEG, декодирование 2K | 181 | 280 | + 55 % |
| nvJPEG, декодирование 4K | 55,6 | 89,2 | + 60 % |
| nvJPEG, декодирование 8K | 13,7 | 22,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, поэтому кадр делится на сегменты так:
| Размер, Мпикс | 4:4:4 | 4:2:0 | |
|---|---|---|---|
| Кадр 8K | 33 | 51 840 | 25 920 |
| Кадр 12K | 75 | 116 640 | 58 320 |
| Кадр 16K | 133 | 207 360 | 103 680 |
У файлов nvJPEG маркеров нет, и весь кадр — один сегмент: кадр любого размера nvJPEG декодирует последовательно, выполняя энтропийное декодирование на процессоре.
Маркеры позволяют декодировать часть изображения. Каждый сегмент начинается с маркера и декодируется независимо от остальных, а сколько в нём блоков MCU, задано рестарт-интервалом. Поэтому по номеру сегмента можно вычислить, какой участок изображения он содержит: у кодера Fastvideo на кадрах этого раздела это полоса 80×8 пикселов при 4:4:4 и 80×16 при 4:2:0. Иначе говоря, маркеры делят изображение на небольшие участки с известными границами, по сути на плитки (тайлы), и найти их можно простым просмотром байтов. Тогда можно декодировать только те сегменты, которые попадают в нужную часть изображения, например в ту, что сейчас видна на экране, а остальные не трогать. Для сшитых изображений это может быть важнее скорости декодирования целиком: их обычно смотрят по частям. В файле без маркеров так нельзя: чтобы добраться до нужного места, приходится энтропийно декодировать всё, что идёт в потоке перед ним. В декодере Fastvideo такого режима сейчас нет, он обрабатывает изображение целиком, но формат это позволяет, и такой режим можно сделать под задачу, где он нужен.
| Fastvideo, к/с | nvJPEG, к/с | Fastvideo, ГБ/с | Разница | |
|---|---|---|---|---|
| Кодирование 8K | 715 | 541 | 71 | + 32 % |
| Кодирование 12K | 335 | 248 | 75 | + 35 % |
| Кодирование 16K | 191 | 137 | 76 | + 39 % |
| Декодирование 8K | 515 | 14,9 | 51 | в 35 раз |
| Декодирование 12K | 221 | 6,05 | 49 | в 37 раз |
| Декодирование 16K | 118 | 3,43 | 47 | в 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 % на обоих кадрах.
| 4:4:4, к/с | 4:2:0, к/с | Изменение | |
|---|---|---|---|
| Fastvideo, кодирование 12K | 335 | 457 | + 36 % |
| Fastvideo, кодирование 16K | 191 | 261 | + 37 % |
| nvJPEG, кодирование 12K | 248 | 360 | + 45 % |
| nvJPEG, кодирование 16K | 137 | 204 | + 49 % |
| Fastvideo, декодирование 12K | 221 | 295 | + 33 % |
| Fastvideo, декодирование 16K | 118 | 165 | + 40 % |
| nvJPEG, декодирование 12K | 6,05 | 10,0 | + 65 % |
| nvJPEG, декодирование 16K | 3,43 | 5,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 разбито на три вызова: первый работает на процессоре, второй передаёт данные на видеокарту, третий работает на видеокарте. Наша программа для nvJPEG замеряет время каждого вызова отдельно и между вызовами ждёт, пока видеокарта закончит работу, поэтому видно, какая часть времени кадра приходится на каждую стадию. Разбор потока и энтропийное декодирование выполняются на центральном процессоре и последовательно: на них уходит 92 % времени на кадре 2K, 93 % на 4K и 91 % на 8K. На видеокарту приходится от 0,7 до 1,9 % — она почти всё это время не занята.
Это и есть цена отсутствия маркеров. Разделить сжатые данные на сегменты нечем, значит, и распараллелить нечего. Поэтому nvJPEG выполняет энтропийное декодирование на процессоре, последовательно.
Декодер nvJPEG работает следующим образом. Сначала процессор разбирает сжатые данные и выполняет энтропийное декодирование. Затем он передаёт полученные результаты на видеокарту. На видеокарте выполняется всё остальное: обратное квантование, обратное дискретное косинусное преобразование и переход из YCbCr в RGB.
Профилировщик подтверждает эту картину со стороны: у декодера nvJPEG на видеокарте работают всего два ядра — одно делает обратное квантование вместе с обратным косинусным преобразованием, другое делает обратное цветовое преобразование, — а ядра энтропийного декодирования нет ни одного. Подробнее об этом написано в разделе 7.
| Где работает | Кадр 2K | Кадр 4K | Кадр 8K | |
|---|---|---|---|---|
| разбор потока и энтропийное декодирование | процессор | 91,9 % | 93,3 % | 91,4 % |
| передача данных с процессора на видеокарту | PCIe | 7,4 % | 5,8 % | 6,7 % |
| обратное квантование, обратное косинусное преобразование, обратное цветовое преобразование | видеокарта | 0,7 % | 0,9 % | 1,9 % |
6.1. Режим пачки у nvJPEG: когда энтропийное декодирование переходит на видеокарту

У библиотеки 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. Другой пример — обработка готовых архивов и больших наборов снимков, где кадры уже лежат на диске.
| Кадров в пачке | 1 | 32 | 64 | 128 |
|---|---|---|---|---|
| Кадров в секунду | 138 | 155 | 422 | 742 |
| Где идёт энтропийное декодирование | процессор | процессор | видеокарта | видеокарта |
7. Что на самом деле делает видеокарта
Все измерения выше сделаны по системным часам. Часы говорят, сколько заняла работа целиком, но не говорят, чем в это время была занята видеокарта. Это показывает профилировщик: он записывает каждый запуск вычислительного ядра и каждое копирование с точностью до наносекунд. Измерения ниже сняты программой Nsight Systems на том же стенде, на кадре 2K, при оптимальном наборе параметров каждого кодека; ни один из кодеков ради этого не менялся.
Величины три. Время ядер на кадр — сколько видеокарта действительно вычисляла, без копирования и без ожидания. Доля времени вычислений — сколько времени на карте работало хоть одно вычислительное ядро. Доля простоя — сколько времени карта не делала ничего: ни вычислений, ни копирования.
| Время ядер на кадр, мс | Доля времени вычислений | Доля простоя | |
|---|---|---|---|
| Fastvideo JPEG, 32 потока | 0,433 | 59 % | 6,6 % |
| nvJPEG, 8 потоков по 2 изображения | 0,027 | 3,1 % | 2,5 % |
По времени вычислений на видеокарте разница — в 16 раз. Это не скорость, а объём работы, который каждый кодек отдаёт видеокарте. У декодера Fastvideo на карте выполняется весь алгоритм, включая энтропийное декодирование; у nvJPEG — только обратное квантование, обратное косинусное преобразование и обратное цветовое преобразование.
Простоя у nvJPEG при этом почти нет, 2,5 %. Карта не бездействует: почти всё остальное время на ней идёт копирование — пока один поток ждёт процессор, другой передаёт данные на видеокарту или забирает готовое изображение. Вычисляет при этом карта 3 % времени.
Имена ядер показывают, что именно вычисляет видеокарта. Профилировщик записывает имя каждого ядра, а имена здесь говорят сами за себя.
| Ядра и их доля во времени ядер | |
|---|---|
| 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 кадров скорость скачком вырастает. Профилировщик показывает, из чего этот скачок состоит.
| Пачка 32 кадра | Пачка 128 кадров | |
|---|---|---|
| Время ядер на кадр, мс | 0,122 | 1,08 |
| Доля времени вычислений | 2,0 % | 79 % |
| Доля простоя | 76 % | 1,4 % |
| Ядро энтропийного декодирования | нет | decodeDcHuffman,95 % времени ядер |
При пачке 32 кадра видеокарта три четверти времени простаивает: она ждёт, пока процессор разберёт сжатые данные. При пачке 128 кадров энтропийное декодирование перешло на видеокарту, простоя почти нет, а время работы ядер на кадр увеличилось почти в девять раз. Ускорение приходит не оттого, что видеокарта стала быстрее вычислять, а оттого, что у неё появилась работа, которую можно разделить между ядрами. С маркерами между ядрами делится один кадр, в режиме пачки — сто двадцать восемь разных кадров.
Чего эти измерения не показывают. Профилировщик видит только видеокарту: сколько времени и на что тратит центральный процессор, он не показывает. В многопоточном режиме ядра разных потоков работают одновременно, поэтому время ядер нельзя складывать с временем кадра из разделов 3 и 4: это разные величины.
8. Скорость вместе с копированием на видеокарту и обратно

Второе измерение: изображение лежит в оперативной памяти, копируется в память видеокарты, обрабатывается и возвращается обратно. Несжатое изображение копируется по 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 раза — скорость всей обработки вместе с копированием по шине на этом компьютере.
| Fastvideo, к/с | nvJPEG, к/с | Fastvideo, ГБ/с (доля) | nvJPEG, ГБ/с (доля) | |
|---|---|---|---|---|
| Кодирование 2K | 3497 | 3532 | 21,8 (85 %) | 22,0 (86 %) |
| Кодирование 4K | 848 | 951 | 21,1 (83 %) | 23,7 (93 %) |
| Кодирование 8K | 192 | 235 | 19,1 (75 %) | 23,4 (92 %) |
| Декодирование 2K | 3632 | 1161 | 22,6 (89 %) | 7,2 (28 %) |
| Декодирование 4K | 895 | 268 | 22,3 (87 %) | 6,7 (26 %) |
| Декодирование 8K | 193 | 65 | 19,2 (75 %) | 6,5 (25 %) |
Гигабайты в секунду в этой таблице — объём несжатых данных в секунду: кадры в секунду, умноженные на число пикселов и на три байта. В скобках — какую долю пропускной способности шины использует кодек; она считается от измеренных 25,5 ГБ/с.
9. Потребление энергии видеокартой

Энергия измерена в тех же условиях, что и скорость в разделе 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 работает на видеокарте целиком, включая энтропийное декодирование: маркеры делят поток на сегменты. Поэтому его энергия на кадр в таблице есть.
| Fastvideo, Дж | nvJPEG, Дж | Разница | |
|---|---|---|---|
| Кодирование 2K | 0,044 | 0,055 | в 1,3 раза |
| Кодирование 4K | 0,17 | 0,19 | в 1,1 раза |
| Кодирование 8K | 0,72 | 0,78 | в 1,1 раза |
| Декодирование 2K | 0,056 | — | — |
| Декодирование 4K | 0,17 | — | — |
| Декодирование 8K | 0,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 работает быстро
Высокая скорость декодирования, показанная в этой статье, возможна только на изображениях с рестарт-маркерами. Таких изображений два вида:
- сжатые кодером Fastvideo: он вставляет маркеры всегда, с рестарт-интервалом 10 блоков MCU при 4:4:4 и 5 при 4:2:0;
- подготовленные заранее другой программой. Для этого подходит
jpegtranиз libjpeg-turbo: он вставляет рестарт-маркеры в уже готовый файл JPEG без потерь — коэффициенты не меняются, и изображение после декодирования остаётся побайтно тем же. Рестарт-интервал задаёт ключ-restart: например,-restart 1B— маркер после каждого блока MCU. Такjpegtranстановится средством подготовить имеющиеся файлы JPEG к быстрому декодированию; так же сделаны варианты файла для теста в разделе 1.1.
Самая высокая скорость — только на специально подготовленных изображениях. С маркером после каждого блока 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. Что в этих измерениях не проверялось
- Цена маркеров при сжатии. Известно, что она входит в приведённые выше 30–39 %, но отдельно не измерена: у кодера Fastvideo нет режима без маркеров.
- Почему декодер Fastvideo при 4:2:0 замедляется на 2K и 4K, а на 8K, 12K и 16K ускоряется. Вдвое меньшее число сегментов — наблюдение из раздела 4.1, а не измеренная причина; к тому же на 8K это наблюдение картину не объясняет. Прореживание 4:2:2 не измерялось вовсе, а 4:2:0 — только в один поток.
- Другие сюжеты и кадры крупнее 16K. Кадры 8K, 12K и 16K сложены из копий кадра 4K; на кадрах с другим содержанием картина может измениться. Кадры крупнее 16K (133 Мпикс) здесь не измерялись.
- Энергия центрального процессора. Счётчик видеокарты учитывает только её собственное потребление, а у декодера nvJPEG большая часть работы идёт на процессоре. Поэтому энергия декодеров не сравнивается.
- Работа центрального процессора. Профилировщик записывает только то, что происходит на видеокарте. Сколько времени и на скольких ядрах процессора идут разбор потока и энтропийное декодирование у nvJPEG, здесь не измерялось.
- Другие видеокарты. Всё измерено на RTX 4090. На картах, где аппаратный блок JPEG есть, картина будет другой.
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.
- Кодек JPEG на CUDA и Fastvideo SDK — то, на чём проводились тесты Fastvideo JPEG.
- Методика тестирования кодеков JPEG и JPEG2000 на CPU и GPU — границы отсчёта, сетка потоков, повторы, измерение энергии.
- Сравнение кодеков JPEG2000 на видеокарте: fvJPEG2000 и nvJPEG2000 — тот же стенд, другой формат.
- JPEG2000, JPEG и PNG: чем отличаются и какой выбрать — чем эти форматы различаются по существу.
- Руководство к Fastvideo SDK (PDF, на английском) — кодек JPEG, рестарт-интервалы кодера и декодера, ограничения.
- Стандарт ITU-T T.81 — описание формата JPEG, включая рестарт-маркеры.
Права на этот материал
Текст статьи — под лицензией CC BY-ND 4.0: перепечатывать целиком и цитировать можно, в том числе в коммерческих изданиях, со ссылкой на источник; переводить и перерабатывать можно с нашего письменного разрешения — напишите нам через форму внизу страницы.
Результаты измерений и таблицы — под лицензией CC BY 4.0: их можно переносить в свои материалы, пересобирать и считать на их основе. Если что-то изменили — скажите, что именно.
Ссылка на источник в обоих случаях: Fastvideo, <адрес статьи>, измерения от 25.09.2026 и 29.09.2026. Просьба приводить условия измерений рядом с результатами: без них результат не воспроизводится.
На изображения ни одна из этих лицензий не распространяется.


