Comments 49
Любопытно, но JPEG формат же уже очень устарел, несмотря на то, что распространен.
Думали вы о JPEG2000 или WebP
JPEG2000 патентно огорожен, и не применим для WEB (не поддерживается браузерами).
Дело не в формате и не в его возрасте, а в алгоритме, который должен быть распараллеливаемым. В алгоритме JPEG2000 вейвлет-преобразование можно распараллелить, а вот энтропийное кодирование вряд ли. Можно в алгоритме JPEG вместо косинусного преобразования сделать вейвлетное, а всё остальное оставить в прежнем виде — так должно работать и это в планах есть. Будет ли лучше сжатие, сказать не могу, а вот формат сжатого изображения точно будет ни с чем не совместимым. Про WebP пока даже не думал.
Хорошая статья, действительно, решаема задача является актуальной. В целом вы не правы в месте «вот время компрессии почему-то считается второстепенным показателем», это не так, именно по этому почти не имеют развития алгоритмы фрактального сжатия, и было бы очень интересно увидеть реализацию такого алгоритма на CUDA. Вот например тут, что-то на эту тему уже есть. Ну и хотелось бы подробностей, в части реализации.
Спасибо. Что касается времени сжатия, то эта тема почти запретная. Есть огромное количество тестов самых разных алгоритмов сжатия, но в единичных случаях указывают время компрессии. Если есть ссылки по скорости сжатия изображений, пожалуйста покажите. Как я уже писал, у кодера Интела из IPP-7.0 результаты отличные, но про скорость сжатия на их сайте ни слова. Понятно, что она может зависеть от многих параметров, но где эти исследования?

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

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

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

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

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.

Ну и так далее. Как это сравнить между собой? Скачать все варианты и протестировать на одном оборудовании и протестировать по одинаковым критериям. С чего и я начал: хороши не те программы, которые у кого-то быстро работают, а которые можно скачать и использовать самому.
По первой ссылке:
Ускорение получилось только на косинусном преобразовании и на квантовании. Это и так было давно известно. Также написано, что Хаффман вообще не для 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 секунды. Получаем скоростное кодирование? Скоростного кодирования не получилось.

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

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

Интересно, «низкая точность деления чисел с плавающей запятой одинарной точности» — это сколько? Главный недостаток какую даёт ошибку? Вы ответ знаете?
На счёт ссылок не знаю, я в свое время сам писал, и не счёл сложность темы достойной публикации и обсуждения, уж больно просто вопрос решался на OpenCL+Qt. Но если очень интересно могу поискать и выложить свои наработки.
Про ошибку смотрите ниже.
На самом деле, про скорость я не спорю, это вполне логично что Nvidia нарочно урезает производительность конкурирующего стандарта по сравнению со своей проприетарной технологией, просто Вы не привели пруфа. Куда важнее, что OpenCL работает и на картах AMD и на любых CPU, а CUDA этим похвастаться не может.
Очень интересно, как вопрос сжатия изображений «больно просто» решается на OpenCL+Qt. И какие результаты по производительности были получены. Пожалуйста расскажите.
Результат деления чисел с плавающей запятой одинарной точности на Fermi GPU равен результату аналогичного деления на CPU, согласно документации (CUDA C Programming Guide)
Речь шла не только о 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 ulp достигается на Fermi GPU. Это как раз compute capability = 2.
т.е. на тех устройствах, что поддерживают double, а я в своем первом комментарии я явно написал про одинарную точность. Я не говорю что double плох, но его поддерживают не все устройства и его обработка требует больше тактов…
Кстати, не обязательно double. Алгоритм DCT можно реализовать через целые числа, что как раз и делают многие кодировщики (cjpeg). Двойная польза: гарантировано побайтовое сходство изображений, закодированных на разных архитектурах и это невероятно важно для embedded без/с медленным fpu. Есть ещё и быстрый целочисленный DCT: менее точный, но тоже обеспечивает побайтовое сходство. На обычных x86 процессорах быстрее процентов на 5, чем обычный целочисленный алгоритм.

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

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

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

Скажите пожалуйста, а Вы не сталкивались с реализациями или исследованиями на тему скоростного сжатия графики алгоритмами без потерь?
Спасибо. Чтобы говорить о быстром сжатии изображений без потерь, нужно сначала определиться с алгоритмами. Если говорить только о графике, то это обычно 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 МБайт/с.
Требование к алгоритму у меня по сути одно — это совместимость с существующими форматами, так как разрабатывать полностью свой стек софта и форматов данных может быть не рационально. Совместимость отчасти превыше всего.

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

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

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

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

Что касается x264, то это сложный алгоритм и я не уверен, что он целиком параллелится для кодера и для декодера, а это очень важно для вычислений на видеокарте. Ещё у этого алгоритма высокие требования к памяти из-за обращений к данным других кадров, а это тоже проблема. В общем, штука сложная, но подумать над этим стоит. Сделать ME/AC быстрее на видеокарте, скорее всего, возможно. Пишут, что для видео монтажа более предпочтителен MJPEG (Motion JPEG), в котором кадры кодируются независимо, а это как раз то, что сделано. При кодировании в JPEG высокая скорость получается из-за разбиения изображения на блоки 8х8 с последующими независимыми вычислениями для данных каждого блока.
Пишут, что как раз с Кеплером будет и отличный аппаратный кодер h264 под названием NVENC. Также обещают, что кодер сделан аппаратно, причём отдельно от куды, в 4 раза быстрее, чем было раньше. На куде можно делать препроцессинг данных, а кодировать на NVENC.
Кстати, использовался NPP, сравнивалась скорость некоторых процедур с ним?
NPP не использовался.
Стадии DCT и квантования примерно такие же по скорости, а в NPP больше от JPEG ничего нет.
Преобразование цвета тоже должно иметь аналогичный порядок по скорости.
Скорость вычисления гистограммы можно сделать раза в 3 выше, чем в NPP и это можно использовать при создании собственных таблиц Хаффмана при кодировании в JPEG.
Only those users with full accounts are able to leave comments. Log in, please.