14 марта 2012 в 18:35

Быстрое сжатие изображений по алгоритму JPEG на CUDA

Краткое содержание: Создан быстрый кодер FVJPEG для сжатия изображений по алгоритму JPEG на видеокартах NVIDIA. Значительное ускорение получено при распараллеливании алгоритма, его реализации и оптимизации с помощью технологии CUDA. По скорости сжатия кодер FVJPEG превосходит все существующие в настоящее время программные и аппаратные решения для компрессии изображений по алгоритму Baseline JPEG.

При сравнении алгоритмов сжатия изображений с потерями, практически всегда обсуждаются степень сжатия и качество получаемой картинки, а вот время компрессии почему-то считается второстепенным показателем. По всей видимости, для большинства приложений этот подход справедлив, но существуют ситуации, когда время сжатия может быть очень важным. Например, при сжатии больших массивов изображений или при работе с оборудованием, способным генерировать огромные объёмы данных, для которых требуется компрессия в режиме реального времени. Такова ситуация при сжатии серий изображений от высокоскоростных видеокамер. Поток данных от типичной быстрой камеры может достигать величины 625 Мбайт в секунду (разрешение 1280 х 1024, 8 бит, 500 кадров в секунду) и выше. Существуют высокоскоростные видеокамеры, которые в онлайне пишут данные через фреймграббер PCI-Express 2.0 x8 в оперативную память компьютера со скоростью 2,4 Гбайт в секунду. Для работы с такими потоками требование распараллеливания алгоритма обработки данных не нужно даже обсуждать — это должно быть по определению. Поэтому для выбора быстрого алгоритма сжатия были сформулированы следующие критерии:

  • возможность распараллеливания алгоритма как для кодирования, так и для декодирования
  • возможность сжатия изображений в 10-20 раз с потерями при приемлемом качестве
  • вычислительная сложность алгоритма должна быть как можно меньше
  • деление задачи на максимально возможное количество подзадач
  • минимальные требования к размеру быстрой памяти для одного потока обработки данных

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

Для начала изучим бенчмарки скорости (производительности) сжатия изображений с потерями по алгоритму Baseline JPEG при условии, что изображение уже загружено в оперативную память и нужно сделать только компрессию. Не будем следовать широко распространённому методу, когда делают сравнение полученного решения с заведомо слабыми конкурентами, поэтому в качестве соперников рассмотрим самые быстрые на сегодня коммерческие решения для многоядерных CPU:

Кодер JPEG из PICTools Photo от компании Accusoft Pegasus (сжатие с производительностью 150-250 Мбайт в секунду, 8 бит, степень сжатия ~ 50%)

Кодер JPEG из IPP-7.0 от компании Intel: uic_transcoder_con.exe, version 7.0 build 205.85, [7.7.1058.205], name ippjy8-7.0.dll+, date Nov 27 2011, 64-бит, официальных данных по скорости сжатия нет, результаты тестирования приведены далее)

Кодер JPEG от компании Norpix для работы со скоростными видеокамерами (сжатие с производительностью 200-250 Мбайт в секунду, 8 бит, степень сжатия неизвестна)

К сожалению, проверить эти данные нет возможности за исключением кодера IPP-7, который сам сообщает о времени кодирования, поэтому просто поверим написанному. Для более подробного анализа также нет данных по производительности каждой стадии алгоритма обработки, поэтому придётся ограничить сравнение только общими показателями производительности при одинаковых параметрах сжатия. Кодек JPEG от Kakadu найти не удалось, так как теперь эта компания выпускает только кодек JPEG2000, а скорость сжатия у libjpeg_simd-6b и libjpeg-turbo оказалась очень низкой.

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

Результаты у лучших коммерческих решений на многоядерных CPU впечатляющие, поэтому очень интересно попытаться их превзойти. Для этого рассмотрим вариант сжатия изображений на видеокарте по алгоритму Baseline JPEG с помощью технологии NVIDIA CUDA. Поскольку стоит задача получения максимальной производительности, то и «железо» должно быть соответствующим. NVIDIA GeForce GTX 580 вполне подойдёт.

В этой области исследований обнаружилось немало проектов и научных работ, утверждающих, что алгоритм JPEG нельзя распараллелить полностью из-за стадии энтропийного кодирования. Поэтому за рубежом были созданы гибридные решения, когда дискретное косинусное преобразование выполнялось на видеокарте, а остальные вычисления делали на CPU. Таким образом, ускорялось выполнение только одной стадии, очевидным образом подходящей для GPU. В итоге добивались небольшого увеличения скорости кодирования, но полученные результаты не смогли соперничать по скорости компрессии с лучшими многопоточными решениями на CPU. Найти информацию о производительных кодерах JPEG на базе видеокарт NVIDIA или ATI, к сожалению, не удалось.

Рассмотрим задачу, в которой исходные несжатые данные изображения находятся в оперативной памяти компьютера и их необходимо сжать в JPEG. Реализация алгоритма Baseline JPEG на видеокарте включает в себя следующие стадии:

  • Загрузка данных из оперативной памяти в видеокарту (Host-to-Device transfer)
  • Преобразование RGB->YCbCr (не нужно для 8-битных изображений)
  • Разбиение изображения на блоки 8х8
  • Смещение (вычитание 128) для каждого пиксела
  • Дискретное косинусное преобразование (DCT) для каждого блока
  • Квантование (Quantization) для каждого блока
  • Переупорядочивание (Zig-zag) для каждого блока
  • Дельта-кодирование (DPCM) для DC от каждого блока
  • Кодирование серий (RLE) для AC от каждого блока
  • Кодирование по Хаффману (Huffman) для AC от каждого блока
  • Установка рестарт-маркеров RSTn для групп блоков
  • Формирование выходного файла: склеивание данных от сжатых блоков, добавление заголовка JFIF
  • Выгрузка JPEG файлов из видеокарты в оперативную память (Device-to-Host transfer)

Вся эта схема была реализована на CUDA. Одна из основных идей стандартного алгоритма JPEG состоит в разбиении изображения на блоки 8х8 с последующей независимой обработкой данных с помощью дискретного косинусного преобразования, что по сути является схемой параллельного алгоритма. Распараллеливание дискретного косинусного преобразования уже было известно и полученные результаты по производительности были намного лучше у GPU, чем у CPU. Стадия дельта-кодирования (DPCM) коэффициентов DC тоже может быть распараллелена. Кодирование серий (RLE) и кодирование по Хаффману выполняются независимо для данных каждого блока 8х8, поэтому они тоже параллелятся. В завершение нужно записать сжатые данные от каждого блока в выходной файл, сформировать из него изображение формата JPEG и отправить файл в оперативную память компьютера. Так что можно утверждать, что практически вся схема кодирования по алгоритму JPEG успешно распараллеливается и этот алгоритм можно целиком реализовать на GPU.

Остаётся вопрос о реализации декодирования. Для этого в стандарте JPEG изначально были предусмотрены маркеры, которые дают возможность выполнять декодирование с произвольного места сжатого изображения, а не только последовательно. К сожалению, в большинстве реализаций на CPU алгоритма сжатия JPEG этих маркеров нет, поэтому в таких ситуациях первая стадия декодирования выполняется последовательно и «чужие» изображения будут декодироваться относительно медленно (PhotoShop ставит эти маркеры при кодировании). Если же при кодировании маркеры были поставлены, то перед началом декодирования делается быстрый поиск всех установленных маркеров и после этого становится возможным выполнять декодирование параллельным образом. В описанной выше схеме сжатия делается установка маркеров после определённого количества блоков 8х8 и в итоге процесс декодирования также получается параллельным. Тем не менее, вопросы декодирования остаются за рамками данной статьи.

Для тестирования программы были выбраны следующие стандартные условия:
  • 8-битные тестовые изображения
  • степень сжатия 50-100%
  • размеры изображений по горизонтали и по вертикали должны быть кратны 8
  • размер исходного файла не более 64 Мбайт

Для тестирования использовалась такая конфигурация компьютера:
  • ASUS P6T Deluxe V2 LGA1366, X58, ATX Core i7 920, 2.67 GHz, DDR-III 6 GB.
  • Видеокарты для вычислений: GeForce GT 240 (cc = 1.2, 96 ядер) или GeForce GTX 580 (cc = 2.0, 512 ядер).
  • Операционная система Windows-7, 64-bit, CUDA 4.1, driver 286.19

Тестовые 8-битные изображения использовались общепринятые (lenna.bmp, boats.bmp), из IPP (uic_test_image.bmp), а cathedral.bmp и big_building.bmp взяты здесь

В нижней строке таблицы для каждого изображения указано соответствие между степенью сжатия и коэффициентом сжатия (во сколько раз уменьшается размер файла) при сжатии с таблицами квантования и Хаффмана, которые приняты в Baseline JPEG по умолчанию.
тестовые изображения

Общее время работы кодека FVJPEG в Windows измерялось с помощью функции QueryPerformanceCounter(). Время выполнения отдельных функций на видеокарте измерялось с помощью профайлера NVIDIA. Результаты профайлера необходимы для детального анализа скорости сжатия каждой стадии алгоритма, что представляет интерес прежде всего для разработчиков. Количество повторов (опция многих программ для увеличения точности измерения времени) во всех тестах равно единице, поскольку повторение вычислений над одними и теми же данными не имеет никакого практического смысла. Таким образом, основной задачей было исследование реальных рабочих режимов функционирования кодировщиков и предельных значений производительности сжатия. Для малых изображений есть разброс 10-20% по скорости кодирования, поэтому брались самые высокие результаты в серии тестов. В тестах участвовали кодер FVJPEG на видеокартах NVIDIA GeForce GT 240 и GeForce GTX 580, а также кодер JPEG из IPP-7.0 на Core i7 920.

В таблице 2 приведены результаты измерений для скорости сжатия по алгоритму JPEG для видеокарты NVIDIA GeForce GT 240 в мегабайтах в секунду для различных 8-битных изображений в зависимости от степени сжатия:
скорость сжатия для видеокарты NVIDIA GeForce GT 240

В таблице 3 приведены результаты измерений скорости сжатия в JPEG для видеокарты NVIDIA GeForce GTX 580 в мегабайтах в секунду:
скорость сжатия для видеокарты NVIDIA GeForce GTX 580

Очень важно, что при измерении скорости сжатия учитывалось время копирования данных на видеокарту и обратно. Дело в том, что время копирования данных в память видеокарты обычно оказывается одной из самых длительных операций при реализации алгоритма сжатия в JPEG на GPU. Если же оценить производительность кодирования без учёта загрузки данных в память видеокарты, т.е. если мы хотим измерить именно производительность вычислений при сжатии изображений с потерями, то для достаточно больших изображений и при степени сжатия 50% получаем скорость компрессии в JPEG порядка 10 Гбайт в секунду и более для GeForce GTX 580. Этот результат является прекрасной иллюстрацией высочайшей эффективности параллельных вычислений на мощных видеокартах.

Для сравнения с кодером из Intel IPP-7.0 (update 6) был использован тот же самый набор изображений и те же самые степени сжатия, что и в тестах для видеокарт NVIDIA. Командная строка имела такой вид: uic_transcoder_con.exe -otest.jpg -ilenna.bmp -t1 -q50 -n8, что означает сжатие изображения lenna.bmp, создание нового изображения test.jpg, используемый алгоритм Baseline JPEG (-jb), измерение времени выполнения программы с повышенной точностью (-t1), степень сжатия 50% (-q50) при распараллеливании на 8 потоков (-n8). Режим работы -m для повторения процедуры сжатия не использовался, поскольку нет практических задач для повторного сжатия одного и того же изображения.

В таблице 4 приведены результаты для производительности кодера JPEG из IPP-7.0 (скорость сжатия Мбайт в секунду / время сжатия изображения в миллисекундах):
скорость сжатия кодера JPEG из IPP-7.0 на CPU Core i7 920

При использовании тестового изображения из IPP-7.0 и при одинаковых параметрах сжатия (uic_test_image.bmp, 1280 x 960, 8 бит, степень сжатия 50%, что соответствует компрессии в 8,1 раз), на видеокарте GeForce GTX 580 получена производительность 2,25 Гбайт в секунду, что заметно лучше (быстрее в 6,7 раз), чем 332 Мбайт в секунду на CPU Core i7 920 при распараллеливании на 8 потоков для кодера JPEG из IPP-7.0. Полученная производительность кодера IPP-7.0 в два раза ниже даже по сравнению с довольно слабой видеокартой GeForce GT 240, которая при тех же параметрах даёт скорость компрессии 680 Мбайт в секунду.

На графике 1 указаны результаты по скорости сжатия тестового изображения cathedral.bmp (2000 x 3008, 8 бит) на видеокартах GeForce GT 240, GeForce GTX 580 (кодер FVJPEG) и CPU Core i7 920 (кодер JPEG из IPP-7.0) для разных значений степени сжатия по алгоритму Baseline JPEG:
Скорость сжатия 8-битного изображения cathedral.bmp в JPEG на GeForce GT 240,  GeForce GTX 580 и CPU Core i7 920

С помощью профайлера NVIDIA были сделаны измерения длительности каждой стадии алгоритма кодирования. В таблице 5 приведены бенчмарки для времени сжатия по алгоритму Baseline JPEG с используемыми по умолчанию таблицами квантования и Хаффмана, при разных степенях сжатия, для видеокарты NVIDIA GeForce GTX 580. Изображение cathedral.bmp, разрешение 2000 х 3008, 8 бит, в скобках после степени сжатия указано, во сколько раз сжимается это изображение:
Время выполнения основных стадий сжатия JPEG на видеокарте GeForce GTX 580

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

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

Анализ времени выполнения каждой стадии алгоритма JPEG на видеокарте даёт следующую картину: одна из самых медленных операций – это загрузка данных из оперативной памяти компьютера в видеокарту. Для больших изображений скорость как загрузки, так выгрузки данных имеют порядок 6 Гбайт/с. Это ограничение обусловлено пропускной способностью шины PCI-Express 2.0, а значительное ускорение в принципе может быть возможно лишь при переходе на следующее поколение PCI-Express (с Gen2 на Gen3). Время загрузки изображения и время выполнения дискретного косинусного преобразования зависят только от размера изображения. В то время как кодирование серий и кодирование по Хаффману зависят от конкретных данных самого изображения, степени сжатия и от размера данных на данном этапе сжатия.

Важным моментом для увеличения производительности является размер изображения. Чем больше размер изображения, тем больше скорость сжатия на видеокарте. По всей видимости, это связано с тем, что данных в небольшом изображении не хватает для полной загрузки видеокарты и часть вычислительных мощностей простаивает. Если же использовать относительно большие кадры (4 Мегабайта и более), то получаем полную загрузку и производительность сжатия на видеокарте увеличивается. Тем не менее, и для небольших изображений есть вариант ускорения: можно загружать одновременно сразу несколько кадров и кодировать их параллельно. Таким образом можно загрузить видеокарту полностью и получить максимальную производительность даже для изображений небольшого размера. Поэтому скорость сжатия для серий небольших кадров будет близкой к тем результатам, которые получены для больших одиночных изображений. Такой режим работы для одновременной загрузки и сжатия нескольких изображений уже протестирован и будет включён в финальную версию кодека FVJPEG.

Также хотелось бы отметить, что результаты, полученные на видеокарте GeForce GTX 580 для скорости сжатия изображений по алгоритму JPEG с потерями, превосходят по производительности все известные аппаратные решения по сжатию изображений на ПЛИС (FPGA) для того же самого алгоритма. Одни из самых быстрых систем сжатия изображений на ПЛИС по алгоритму JPEG предлагают следующие компании:

Barco BA116 JPEG Encoder (High speed baseline DCT-based JPEG color encoder) — функция аппаратного кодирования в JPEG для FPGA, производительность до 140 Мбайт/с.

Cast Inc. (JPEG-C Baseline JPEG Compression Codec Core) — функция аппаратного сжатия в джипег для FPGA, производительность до 275 Мбайт/с для Xilinx Virtex-6, до 280 Мбайт/с для Altera FPGA Stratix IV.

Visengi (JPEG / MJPEG Hardware Compressor IP Core) — функция аппаратного кодирования в джипег для FPGA Virtex-5, производительность до 405 Мбайт/с.

Alma-Tech (SVE-JPEG-E, SpeedView Enabled JPEG Encoder Megafunction) — функция аппаратного сжатия по Baseline JPEG для FPGA Altera/Xilinx, производительность до 500 Мбайт/с.

На специализированных выставках встречались сообщения от частных компаний о создании кодировщиков JPEG на ПЛИС с производительностью до 680 Мбайт в секунду (четыре отдельных блока, работающих параллельно и дающих по 170 Мбайт в секунду каждый), но подробностей про такие решения найти не удалось.

Сравнивая программный кодер на GPU с аппаратными кодерами JPEG на ПЛИС, стоит отметить, что кроме более высокой производительности полученного решения на GPU, по сравнению с Verilog/VHDL, код на Си для CUDA намного более понятный и приспособленный к модификации для создания на его базе новых, более сложных систем обработки и сжатия изображений. Понятно, что у ПЛИС есть свои плюсы, но мы ограничимся лишь рассмотрением вопроса скорости вычислений.

Для полноты картины нужно не забывать и о существующих недостатках технологий параллельных вычислений на видеокарте. Во-первых, вычисления на видеокарте имеют смысл только для распараллеливаемых алгоритмов, что означает, что для многих последовательных алгоритмов такой возможности просто нет, поэтому для их реализации однозначно потребуется программное обеспечение для CPU. Также технология CUDA может быть использована только в видеокартах производства NVIDIA, а самые последние достижения (технология Fermi) доступны только для последних моделей видеокарт. В принципе, существует стандарт OpenCL, который подходит для видеокарт различных производителей, но он не даёт максимальной производительности для видеокарт NVIDIA и вообще, универсальность такого типа решения для всех существующих архитектур видеокарт пока кажется спорной. Важно, что у потоковых мультипроцессоров на видеокартах очень малый размер быстрой разделяемой памяти, что вносит дополнительные ограничения на используемые алгоритмы и их эффективность, а доступная (относительно медленная) память GDDR5 на данный момент не более 6 Гигабайт на видеокарту, в то время как для CPU размер оперативной памяти может превышать сотню гигабайт. Чтобы получить высокую производительность, необходимо добиться максимальной загрузки видеокарты, а это возможно только для параллельных алгоритмов и для больших объёмов данных. Для вычислений на GPU всегда нужно сначала копировать данные в видеокарту, что вносит дополнительную задержку и увеличивает время расчётов. Поэтому при проектировании высокопроизводительного решения на видеокарте нужно принимать во внимание разнообразные особенности алгоритма и возможности его реализации в конкретном «железе».

В данной статье представлено решение для быстрого сжатия 8-битных изображений по стандартному алгоритму JPEG на одной видеокарте. В резерве остались различные способы масштабирования производительности для такого решения, поскольку уже сейчас у NVIDIA есть технология распараллеливания таких задач на несколько видеокарт, что в принципе может дать возможность для дальнейшего кратного увеличения скорости сжатия. Использование более мощных видеокарт вроде GeForce GTX 590 также должно привести к улучшению результатов. Ещё существует потенциальная возможность для ускорения алгоритма при распараллеливании стадий копирования и вычислений. Следующее, более мощное поколение видеокарт NVIDIA тоже может рассматриваться в контексте увеличения производительности сжатия. Таким образом, технологии параллельных вычислений на видеокартах дают широкие возможности для создания быстрых алгоритмов обработки данных и по-прежнему есть что улучшать и куда стремиться. Также представляют большой интерес для дальнейших исследований оптимизация полученного решения, другие алгоритмы для быстрого сжатия изображений и видео (MJPEG), в том числе и без потерь.

Программное обеспечение для сжатия изображений на видеокарте, описанное в статье, является результатом предварительных исследований и пока не существует в виде законченного коммерческого продукта. Релиз кодека FVJPEG и соответствующего SDK для быстрого сжатия изображений на GPU NVIDIA по алгоритму Baseline JPEG для Windows/Linux ожидается в ближайшее время.
Серженко Фёдор @fyodorser
карма
24,0
рейтинг 0,0
Image & Video Processing on CUDA
Самое читаемое Разработка

Комментарии (49)

  • +19
    Кат. Пожалуйста.
  • 0
    Любопытно, но JPEG формат же уже очень устарел, несмотря на то, что распространен.
    Думали вы о JPEG2000 или WebP
    • +3
      JPEG2000 патентно огорожен, и не применим для WEB (не поддерживается браузерами).
    • +1
      Дело не в формате и не в его возрасте, а в алгоритме, который должен быть распараллеливаемым. В алгоритме JPEG2000 вейвлет-преобразование можно распараллелить, а вот энтропийное кодирование вряд ли. Можно в алгоритме JPEG вместо косинусного преобразования сделать вейвлетное, а всё остальное оставить в прежнем виде — так должно работать и это в планах есть. Будет ли лучше сжатие, сказать не могу, а вот формат сжатого изображения точно будет ни с чем не совместимым. Про WebP пока даже не думал.
  • –9
    О Боже! Что ЭТО?? Где кат??
  • +19
    хороший курсовик скачать бесплатно без смс полную версию
    • +2
      *Всплывающее окошко"
      Введите номер своего телефона.
    • +1
      Подсказываете гуглу?
  • +1
    Хорошая статья, действительно, решаема задача является актуальной. В целом вы не правы в месте «вот время компрессии почему-то считается второстепенным показателем», это не так, именно по этому почти не имеют развития алгоритмы фрактального сжатия, и было бы очень интересно увидеть реализацию такого алгоритма на CUDA. Вот например тут, что-то на эту тему уже есть. Ну и хотелось бы подробностей, в части реализации.
    • +1
      Спасибо. Что касается времени сжатия, то эта тема почти запретная. Есть огромное количество тестов самых разных алгоритмов сжатия, но в единичных случаях указывают время компрессии. Если есть ссылки по скорости сжатия изображений, пожалуйста покажите. Как я уже писал, у кодера Интела из IPP-7.0 результаты отличные, но про скорость сжатия на их сайте ни слова. Понятно, что она может зависеть от многих параметров, но где эти исследования?

      Практическая применимость фрактального сжатия для меня не ясна и это останавливает. Наверное, нужно учить матчасть. Вот быстрый кодер джипега — это реальная задача, у которой я вижу ряд применений, а какие есть уникальные приложения для фрактального сжатия?
  • +2
    Лучше бы выложили исходники на гитхаб, а не пихали типичную в своей бесполезности статью из конференций. На хабре и так хватает измышлений о гигабайтах оперативки и известий о том, что параллелизуемые алгоритмы на GPU увеличить на порядок скорость обработки. А порядок действий при кодировании JPEG можно и в Википедии посмотреть.

    Найти информацию о производительных кодерах JPEG на базе видеокарт NVIDIA или ATI, к сожалению, не удалось.
    Да неужели?
    • 0
      Приятно видеть эксперта. Если Вы попробуете зайти на любую из этих ссылок Гугла, прочитаете то, что там написано и разделите размер файла на время кодирования, будете удивлены. Попробуйте. И тогда поделитесь со всеми результатами изысканий. Очень жду ссылку не на Гугл, а на реальный документ и значение скорости сжатия в джипег.
      • –1
        Вот как раз скоростям действительно реализованных библиотек, например, code.google.com/p/jpeg-opencl/, я не удивлён. Всё упирается в io файловой системы, а не в шину PCI-E. У меня чтение в 100 МБ/c. Был бы SSD — было бы где-то 250 МБ/c. Это как раз то, что предлагают упомянутые в статье продукты. Откуда я должен взять цифру в 500 МБ/c? Откуда эти числа взяли вы? Генерировать случайные изображения в памяти и потом их не сохранять? Выполнять конвертирование одного и того же файла (опять же без сохранения)? Вряд ли найдётся программа, которая предлагает такой странный функционал.
        • +1
          Вы невнимательно читали. В тексте указан источник данных — оборудование, которое действительно генерирует такие потоки данных. Сжимать изображения с диска не имеет смысла из-за ограничения скорости чтения обычного HDD. Хотя и SSD бывают разные. Например, такие: OCZ RevoDrive

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

          Кстати, ссылка из Вашего предыдущего поста будет или увы?
          • –1
            Вот со страницы поиска:

            1 результат: www.eecg.toronto.edu/~moshovos/CUDA08/arx/JPEG_report.pdf — расписано всё по шагам, местами ускорение *180

            2 результат: www.fastvideo.ru/info/cuda/cuda-jpeg-encoder.htm — снова гигантские скорости в 2 ГБ/c на GTX 580. Не знаю, что они замеряли, но очень похоже на ваш результат.

            5 результат: cuj2k.sourceforge.net/Benchmark.html — эти тестируют jpeg и jpeg2000 на 280GTX, не очень сравнивается с GTX 580.

            Ну и так далее. Как это сравнить между собой? Скачать все варианты и протестировать на одном оборудовании и протестировать по одинаковым критериям. С чего и я начал: хороши не те программы, которые у кого-то быстро работают, а которые можно скачать и использовать самому.
            • 0
              По первой ссылке:
              Ускорение получилось только на косинусном преобразовании и на квантовании. Это и так было давно известно. Также написано, что Хаффман вообще не для GPU. Это решение задачи кодирования в JPEG? Видимо, нет. Читаем далее про декодирование. Понятно, что означает фраза «Results of the experiment were not good»? Далее ещё лучше: «CUDA code was 3 times slower then naïve CPU implementation».

              По второй ссылке ещё интереснее:
              Дело в том, что я работаю в компании «Фаствидео» и этот текст написан мной 2-3 месяца назад. Сейчас результаты стали лучше, но они не окончательные.

              Третья ссылка:
              Во-первых это JPEG2000. Теперь смотрим на график, делим 83 мегабайта на 4 секунды. Получаем скоростное кодирование? Скоростного кодирования не получилось.

              Как сравнивать? Сравнивать нужно скорости кодирования, а не впечатления. Желательно с учётом того, на каком железе получены результаты.
              • 0
                С этого и стоило начинать, что вы работаете на Фаствидео и описанный алгоритм реализован в программе Fastvideo Lab, которая распространяется в аппаратном комплексе. Вы же написали «Программное обеспечение для сжатия изображений на видеокарте, описанное в статье, является результатом предварительных исследований и пока не существует в виде законченного коммерческого продукта», хотя Fastvideo Lab обещает тот же Baseline JPG с тем же пиком в 3,4 ГБ/c, что и здесь в статье. Традиция «К сожалению, проверить эти данные нет возможности за исключением кодера IPP-7, который сам сообщает о времени кодирования, поэтому просто поверим написанному» продолжается.
                • –1
                  По всей видимости, Вам виднее, что входит в Fastvideo Lab и что там обещают. А для остальных могу сообщить, что библиотеки сжатия там нет — это отдельный проект, который будет использоваться не только для наших видеокамер. Вы снова попали пальцем в небо. Вы же пошли в Гугл искать бенчмарки с высокой скоростью сжатия, «которых там много». Результаты будут? Пока есть масса недовольства по любому поводу. Желаю удачи.
  • 0
    Сравнивая программный кодер на GPU с аппаратными кодерами JPEG на ПЛИС, стоит отметить, что кроме более высокой производительности полученного решения на GPU, по сравнению с Verilog/VHDL, код на Си для CUDA намного более понятный и приспособленный к модификации для создания на его базе новых, более сложных систем обработки и сжатия изображений

    Есть еще вот такая вещь: www.maxeler.com/content/software/
    Жутко дорогая правда.
    • 0
      Спасибо за ссылку. Система супер, но ничего по сжатию изображений на FPGA там не нашёл. Надо сказать, что цитированные в статье кодеры джипега на FPGA тоже очень недешёвые.
      • 0
        А там и не должно быть ничего про сжатие изображений. Это компилятор джава-подобного языка в FPGA, он решает проблему сложности программирования последнего, о которой вы упомянули.
  • 0
    Про OpenCL хорошо сказано, главное без пруфа, я сразу поверил! А еще не указан главный (на мой взгляд) недостаток GPU — низкая точность деления чисел с плавающей запятой одинарной точности, т.е. вы не получите один результат запустив алгоритм, использующий операции деления, на CPU и GPU. Решается использованием double.
    • 0
      Пруфа для OpenCL у меня действительно нет. И ссылок про быстрое сжатие на OpenCL я тоже не нашёл. Возможно, эти ссылки есть у Вас? Давайте их обсудим. Готов пересмотреть свой взгляд при наличии аргументов.

      Интересно, «низкая точность деления чисел с плавающей запятой одинарной точности» — это сколько? Главный недостаток какую даёт ошибку? Вы ответ знаете?
      • 0
        На счёт ссылок не знаю, я в свое время сам писал, и не счёл сложность темы достойной публикации и обсуждения, уж больно просто вопрос решался на OpenCL+Qt. Но если очень интересно могу поискать и выложить свои наработки.
        Про ошибку смотрите ниже.
        На самом деле, про скорость я не спорю, это вполне логично что Nvidia нарочно урезает производительность конкурирующего стандарта по сравнению со своей проприетарной технологией, просто Вы не привели пруфа. Куда важнее, что OpenCL работает и на картах AMD и на любых CPU, а CUDA этим похвастаться не может.
        • 0
          Очень интересно, как вопрос сжатия изображений «больно просто» решается на OpenCL+Qt. И какие результаты по производительности были получены. Пожалуйста расскажите.
    • +1
      Результат деления чисел с плавающей запятой одинарной точности на Fermi GPU равен результату аналогичного деления на CPU, согласно документации (CUDA C Programming Guide)
      • 0
        Речь шла не только о Fermi. Посмотрите Table C-1, там есть оговорка:
        0 for compute capability ≥ 2 when compiled with -prec-div=true
        2 (full range), otherwise
        и подробнее в C.2.1. Если коротко, то смысл в том, что округление с точностью 0 ulp можно получить только на устройствах с нативной поддержкой double и только при указании опции компилятора -prec-div=true. В остальных случаях будет 2 ulp. Я в подробности не вникал, т.к. больше не увлекаюсь Nvidia но, очевидно, в этом случае компилятор просто приводит float к double для достижения необходимой точности.
        • 0
          Да, вы правы. Но я указал в своем комментарии, что 0 ulp достигается на Fermi GPU. Это как раз compute capability = 2.
          • 0
            т.е. на тех устройствах, что поддерживают double, а я в своем первом комментарии я явно написал про одинарную точность. Я не говорю что double плох, но его поддерживают не все устройства и его обработка требует больше тактов…
    • 0
      Кстати, не обязательно double. Алгоритм DCT можно реализовать через целые числа, что как раз и делают многие кодировщики (cjpeg). Двойная польза: гарантировано побайтовое сходство изображений, закодированных на разных архитектурах и это невероятно важно для embedded без/с медленным fpu. Есть ещё и быстрый целочисленный DCT: менее точный, но тоже обеспечивает побайтовое сходство. На обычных x86 процессорах быстрее процентов на 5, чем обычный целочисленный алгоритм.

      Впрочем, у меня есть подозрение, что double в промежуточных операциях не дают в итоге результат отличный от float. По крайней мере double dct не реализуют библиотеки с libjpeg-совместимым api (кандидат на замену — libjpeg-turbo, пользователи Gentoo знают). Если бы это хоть на йоту улучшало результат, такой double dct хотя бы предусмотрели в api). Но это только предположение.
      • 0
        Когда пишут «быстрый», очень желательно напомнить, о какой скорости сжатия идёт речь. Пусть и при самых благоприятных условиях теста. То же самое касается и приставки «турбо». Сколько получилось? Насколько я знаю, получилось крайне мало. Это такой маркетинговый приём, когда пишут про ускорение по отношению к предыдущей версии, а про абсолютные значения просто забывают. Давайте о них вспомним и маркетинговые фокусы отойдут на второй план.
  • 0
    Можно два слова об области применения такого суперскоростного сжатия именно на PC? Только эти высокоскоростные видеокамеры? Что они снимают, где применяются?
    • +1
      Для скоростных видеокамер это просто нужно по работе. Камеры пишут данные напрямую в память компьютера и проблема в том, как обеспечить длительную запись. Можно сжать поток в 10-20 раз и успеть записать его на HDD/SSD. Такой софт интересует также производителей сканеров. Это нужно и для обычных камер, прежде всего для задач машинного зрения, потому что потоки данных на современных видеокамерах очень часто получаются значительные. Причём решение может быть комплексное, т.е. включать в себя калибровку, фильтрацию, восстановление цвета и сжатие. Что касается сжатия больших архивов изображений, это тоже вполне может быть. Наверное, есть и другие приложения.

      Приложений у скоростных видеокамер немало:
      Научно-исследовательские задачи в области регистрации быстрых процессов
      Испытания, тестовые лаборатории, контроль качества на производстве
      Настройка и диагностика скоростных производственных линий, поиск неисправностей
      Спорт: анализ движений спортсмена, видеозапись спортивных соревнований
      Микроскопия, спектроскопия, биомеханика, биология, медицина
      Телевидение, кинопроизводство, 3D-съёмка
      Учебный процесс в высших учебных заведениях

      Вот пара интересных роликов:
      Полярная сова
      Выстрел из лука
    • +1
      Ну ещё промышленные камеры относительно высокого разрешения.
      Вот у меня практическая задача — идёт поток шестнадцатибитных картинок (65536 градаций серого) 1024x1024 при 30 кадрах в секунду (либо 2048x2048 при 8 FPS), и его надо жать в реальном времени в J2K. Вроде и немного — 60-65 мегабайт в секунду всего. Так вот ведь нет хорошего, быстрого и простого в использовании кодека. IPP требует изрядной обвязки и копания в дебрях JPEG, LEAD поддерживает 16 bit, но они зачем-то завязали всё на DirectShow (это при 16 битах-то). Другие библиотечные функции не могут ужать/распаковать 1024x1024/16 bit за 20-25 миллисекунд даже на мощном компьютере. И в основном производительные кодеки поддерживают восьмибитные градации серого либо цвет, но не 16 бит.
      • 0
        Есть ещё один тип приложений для видеокамер. Это касается цветных камер с приличным разрешением и частотой кадров. С видеокамеры идёт поток данных, для которого нужно сначала применить «дебайер» (восстановить цвет для каждого пиксела). При этом размер данных вырастает в 3 раза. Затем можно сжимать цветные изображения в JPEG и записывать сжатый поток либо в оперативку, либо на HDD/SSD. Сейчас такие решения часто делают на встроенных в камеру FPGA, что очень громоздко. Вычислений в такой схеме много и все они распраллеливаются, а это и требуется для видеокарты.
    • 0
      В обработке медицинских изображений часто нужно рендерить на сервере и показывать на не очень мощных клиентах. Рендерить на клиенте не получается из-за большого обьема модели.
  • 0
    А это только мне одному кажется, что проблема копирования данных на видеокарту несколько преувеличена? Все современные видеокарты умеют считать и загружать данные одновременно, а на больших потоках данных всегда достаточно, т.е. вместо падения производительности можно просто получить некоторую задержку. Т.е. пока грузится новая картинка, считать предыдущую картинку. Но это как всегда компромис между частотой обновления и задержкой…
    • +1
      Может проблема и преувеличена, но она есть. Максимальная скорость загрузки данных в настоящее время порядка 6 Гбайт в секунду. И далеко не все видеокарты умеют считать и загружать данные одновременно. У NVIDIA это умеют делать только последние модели (технология Fermi, compute capability =2.0). В статье написано, что этот метод ускорения будет использован, но пока решение не готово. Поскольку скорость вычислений может достигать 10 Гбайт в секунду, скорость копирования является существенным ограничением.
  • 0
    Не планируете реализовать декомпрессор на cuda? Если даже он может декомпрессить только то, что FVJPEG сжал — уже будет очень полезно, так как это позволит съэкономить кучу времени на пересылке сырых картинок в видео карточку и задача пережатия или процессинга готовых картинок на лету становится уже реальной.
    • 0
      Декомпрессор на CUDA точно будет. Для этого маркеры джипега и ставятся. А без маркеров быстрое декодирование не получится. Мысль на счёт пересылки сжатых данных в видеокарту с последующей декомпрессией была, но чёткой постановки задачи не получилось. Возможно, это могло бы быть интересным для разработчиков игр, но я в этом не специалист.
      • 0
        Декодер уже готов. При сжатии тестовых изображений с размером более 6 МБайт с качеством 50%, что примерно соответствует сжатию в 12 раз, получена скорость декодирования 3,2 ГБайт/с (за 1 секунду программа выдаёт 3,2 ГБайт несжатых данных). Сжатие с тем же качеством программа может делать с производительностью 3,4 ГБайт/с. Если же понизить планку качества, т.е. если увеличить степень сжатия, то скорость декодирования будет выше скорости кодирования.
  • 0
    Очень интересная статья, спасибо за описание подхода к действительно актуальной задаче.

    Скажите пожалуйста, а Вы не сталкивались с реализациями или исследованиями на тему скоростного сжатия графики алгоритмами без потерь?
    • 0
      Спасибо. Чтобы говорить о быстром сжатии изображений без потерь, нужно сначала определиться с алгоритмами. Если говорить только о графике, то это обычно JPEG-LS и JPEG2000. На CPU решения есть у уже упоминавшихся Accusoft Pegasus, Intel, Kakadu и у многих других. Kakadu считается одним из самых быстрых. На CUDA существует реализация JPEG-LS, но данных о скорости сжатия нет. Мне кажется, что на CUDA можно сделать быстрый JPEG2000 без потерь, по крайней мере, в упрощённом варианте. И быстрый JPEG-LS тоже можно. Алгоритмов сжатия без потерь немало, но они практически все нераспараллеливаемые. Если я ошибаюсь, пожалуйста поправьте. Поэтому сначала нужно придумать схему параллельного алгоритма для сжатия без потерь. Вопрос очень интересный.

      Вот что есть по аппаратным решениям:
      Alma-Tech (JPEG2K-E JPEG 2000 Encoder Megafunction) — функция аппаратного кодирования в JPEG2000 для FPGA Altera/Xilinx, производительность до 150 МБайт/с.
      Barco BA130 JPEG 2000 Sub-frame latency Encoder (Real-time JPEG 2000 encoder core for high-speed and low-latency applications) — функция аппаратного кодирования в JPEG2000 для FPGA, производительность до 500 МБайт/с.
      IntoPix (Digital Cinema JPEG 2000 Encoders & Decoders IP-cores) — функция аппаратного кодирования в JPEG2000 для FPGA Xilinx, производительность до 720 МБайт/с.
      • 0
        Требование к алгоритму у меня по сути одно — это совместимость с существующими форматами, так как разрабатывать полностью свой стек софта и форматов данных может быть не рационально. Совместимость отчасти превыше всего.

        Алгоритмов сжатия без потерь немало, но они практически все нераспараллеливаемые. Если я ошибаюсь, пожалуйста поправьте.

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

        Спасибо за консультацию! Постараюсь поближе ознакомиться с предложенными Вами решениями.
  • 0
    Было бы полезно видеть эту разработку в качестве плагина к Photoshop/Acdsee/Picasa!

    Кстати, уже Kepler вышел, а качественного x264 на GPU до сих пор нет. Разработчики то же самое говорили, что ME/AC не сильно быстрее на GPU, а в этой статье вижу что всё возможно.
    • 0
      Мне кажется, что для сжатия одного изображения скорость не очень важна. Разницы между сжатием за 0,01 секунды и 0,1 секунды практически нет. Зато это точно имеет смысл для серий изображений. Возможно, скорость будет важна для сжатия изображений большого размера, если вариант Baseline JPEG будет приемлемым.

      Что касается x264, то это сложный алгоритм и я не уверен, что он целиком параллелится для кодера и для декодера, а это очень важно для вычислений на видеокарте. Ещё у этого алгоритма высокие требования к памяти из-за обращений к данным других кадров, а это тоже проблема. В общем, штука сложная, но подумать над этим стоит. Сделать ME/AC быстрее на видеокарте, скорее всего, возможно. Пишут, что для видео монтажа более предпочтителен MJPEG (Motion JPEG), в котором кадры кодируются независимо, а это как раз то, что сделано. При кодировании в JPEG высокая скорость получается из-за разбиения изображения на блоки 8х8 с последующими независимыми вычислениями для данных каждого блока.
      • 0
        Пишут, что как раз с Кеплером будет и отличный аппаратный кодер h264 под названием NVENC. Также обещают, что кодер сделан аппаратно, причём отдельно от куды, в 4 раза быстрее, чем было раньше. На куде можно делать препроцессинг данных, а кодировать на NVENC.
  • 0
    Кстати, использовался NPP, сравнивалась скорость некоторых процедур с ним?
    • 0
      NPP не использовался.
      Стадии DCT и квантования примерно такие же по скорости, а в NPP больше от JPEG ничего нет.
      Преобразование цвета тоже должно иметь аналогичный порядок по скорости.
      Скорость вычисления гистограммы можно сделать раза в 3 выше, чем в NPP и это можно использовать при создании собственных таблиц Хаффмана при кодировании в JPEG.

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