![]() |
![]() |
Главная | E-mail | 08.12.2023 |
![]() |
||
Главная страница | О журнале | Авторам | Редколлегия | Контакты | ||
![]() |
||
Научно-технический интернет-журнал Свидетельство о регистрации Эл № ФС 77-31314 |
|
Обработка видеосигнала
Дата публикации : 22.03.2012 | Просмотров : 1029 |
Использование технологии CUDA для быстрого сжатия изображений по алгоритму JPEG При сравнении алгоритмов сжатия изображений с потерями, практически всегда обсуждаются степень сжатия и качество получаемой картинки, а вот время компрессии почему-то считается второстепенным показателем. По всей видимости, для большинства приложений этот подход справедлив, но существуют ситуации, когда время сжатия может быть очень важным. Например, при сжатии больших массивов изображений или при работе с оборудованием, способным генерировать огромные объёмы данных, для которых требуется компрессия в режиме реального времени. Такова ситуация при сжатии серий изображений от высокоскоростных видеокамер. Поток данных от типичной быстрой камеры может достигать величины 625 Мбайт в секунду (разрешение 1280 х 1024, 8 бит, 500 кадров в секунду) и выше. Существуют высокоскоростные видеокамеры, которые в онлайне пишут данные через фреймграббер PCI-Express 2.0 x8 в оперативную память компьютера со скоростью 2,4 Гбайт в секунду. Для работы с такими потоками требование распараллеливания алгоритма обработки данных не нужно даже обсуждать - это должно быть по определению. Поэтому для выбора быстрого алгоритма сжатия были сформулированы следующие критерии:
Этим требованиям алгоритм JPEG соответствует полностью. Вполне возможно, что есть и другие алгоритмы сжатия с потерями, которые удовлетворяют этим условиям, но здесь рассмотрим только вариант с JPEG. Для начала изучим бенчмарки скорости (производительности) сжатия изображений с потерями по алгоритму Baseline JPEG при условии, что изображение уже загружено в оперативную память и нужно сделать только компрессию. Не будем следовать широко распространённому методу, когда делают сравнение полученного решения с заведомо слабыми конкурентами, поэтому в качестве соперников рассмотрим самые быстрые на сегодня коммерческие решения для многоядерных CPU:
Поскольку речь идёт о реализации стандарта Baseline JPEG с фиксированными таблицами квантования и Хаффмана, то качество сжатого изображения и коэффициент сжатия однозначно определяются параметрами компрессии, поэтому нет необходимости в измерениях PSNR и в визуальной оценке качества. Тем не менее, измерения PSNR и визуальная оценка качества проводились для всех тестов. Результаты у лучших коммерческих решений на многоядерных CPU впечатляющие, поэтому очень интересно попытаться их превзойти. Для этого рассмотрим вариант сжатия изображений на видеокарте по алгоритму Baseline JPEG с помощью технологии NVIDIA CUDA. Поскольку стоит задача получения максимальной производительности, то и "железо" должно быть соответствующим. NVIDIA GeForce GTX 580 вполне подойдёт. В этой области исследований обнаружилось немало проектов и научных работ, утверждающих, что алгоритм JPEG нельзя распараллелить полностью из-за стадии энтропийного кодирования. Поэтому за рубежом были созданы гибридные решения, когда дискретное косинусное преобразование выполнялось на видеокарте, а остальные вычисления делали на CPU. Таким образом, ускорялось выполнение только одной стадии, очевидным образом подходящей для GPU. В итоге добивались небольшого увеличения скорости кодирования, но полученные результаты не смогли соперничать по скорости компрессии с лучшими многопоточными решениями на CPU. Найти информацию о производительных кодерах JPEG на базе видеокарт NVIDIA или ATI, к сожалению, не удалось. Рассмотрим задачу, в которой исходные несжатые данные изображения находятся в оперативной памяти компьютера и их необходимо сжать в JPEG. Реализация алгоритма Baseline JPEG на видеокарте включает в себя следующие стадии:
Вся эта схема была реализована на CUDA. Одна из основных идей стандартного алгоритма JPEG состоит в разбиении изображения на блоки 8х8 с последующей независимой обработкой данных с помощью дискретного косинусного преобразования, что по сути является схемой параллельного алгоритма. Распараллеливание дискретного косинусного преобразования уже было известно и полученные результаты по производительности были намного лучше у GPU, чем у CPU. Стадия дельта-кодирования (DPCM) коэффициентов DC тоже может быть распараллелена. Кодирование серий (RLE) и кодирование по Хаффману выполняются независимо для данных каждого блока 8х8, поэтому они тоже параллелятся. В завершение нужно записать сжатые данные от каждого блока в выходной файл, сформировать из него изображение формата JPEG и отправить файл в оперативную память компьютера. Так что можно утверждать, что практически вся схема кодирования по алгоритму JPEG успешно распараллеливается и этот алгоритм можно целиком реализовать на GPU. Остаётся вопрос о реализации декодирования. Для этого в стандарте JPEG изначально были предусмотрены маркеры, которые дают возможность выполнять декодирование с произвольного места сжатого изображения, а не только последовательно. К сожалению, в большинстве реализаций на CPU алгоритма сжатия JPEG этих маркеров нет, поэтому в таких ситуациях первая стадия декодирования выполняется последовательно и "чужие" изображения будут декодироваться относительно медленно (PhotoShop ставит эти маркеры при кодировании). Если же при кодировании маркеры были поставлены, то перед началом декодирования делается быстрый поиск всех установленных маркеров и после этого становится возможным выполнять декодирование параллельным образом. В описанной выше схеме сжатия делается установка маркеров после определённого количества блоков 8х8 и в итоге процесс декодирования также получается параллельным. Тем не менее, вопросы декодирования остаются за рамками данной статьи. Для тестирования программы были выбраны следующие стандартные условия:
Тестовые 8-битные изображения использовались общепринятые (lenna.bmp, boats.bmp), из IPP (uic_test_image.bmp), а cathedral.bmp и big_building.bmp взяты отсюда: http://www.imagecompression.info/test_images/ В нижней строке таблицы для каждого изображения указано соответствие между степенью сжатия и коэффициентом сжатия (во сколько раз уменьшается размер файла) при сжатии с таблицами квантования и Хаффмана, которые приняты в Baseline JPEG по умолчанию.
В таблице 2 приведены результаты измерений для скорости сжатия по алгоритму JPEG для видеокарты NVIDIA GeForce GT 240 в мегабайтах в секунду для различных 8- битных изображений в зависимости от степени сжатия:
Для сравнения с кодером из 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 (скорость сжатия Мбайт в секунду / время сжатия изображения в миллисекундах):
На графике 1 указаны результаты по скорости сжатия тестового изображения cathedral.bmp (2000 x 3008, 8 бит) на видеокартах GeForce GT 240, GeForce GTX 580 (кодер FVJPEG) и CPU Core i7 920 (кодер JPEG из IPP-7.0) для разных значений степени сжатия по алгоритму Baseline JPEG:
Таким образом, показана принципиальная возможность очень быстрого сжатия изображений на видеокарте по алгоритму JPEG, причём для довольно широкого класса графических карт NVIDIA, в том числе бюджетных и даже мобильных. При этом полученные результаты заметно превосходят те бенчмарки по скорости кодирования в JPEG, которые мы видели для самых быстрых решений на многоядерных CPU. Анализ времени выполнения каждой стадии алгоритма JPEG на видеокарте даёт следующую картину: одна из самых медленных операций - это загрузка данных из оперативной памяти компьютера в видеокарту. Для больших изображений скорость как загрузки, так выгрузки данных имеют порядок 6 Гбайт/с. Это ограничение обусловлено пропускной способностью шины PCI-Express 2.0, а значительное ускорение в принципе может быть возможно лишь при переходе на следующее поколение PCI-Express (с Gen2 на Gen3). Время загрузки изображения и время выполнения дискретного косинусного преобразования зависят только от размера изображения. В то время как кодирование серий и кодирование по Хаффману зависят от конкретных данных самого изображения, степени сжатия и от размера данных на данном этапе сжатия. Важным моментом для увеличения производительности является размер изображения. Чем больше размер изображения, тем больше скорость сжатия на видеокарте. По всей видимости, это связано с тем, что данных в небольшом изображении не хватает для полной загрузки видеокарты и часть вычислительных мощностей простаивает. Если же использовать относительно большие кадры (4 Мегабайта и более), то получаем полную загрузку и производительность сжатия на видеокарте увеличивается. Тем не менее, и для небольших изображений есть вариант ускорения: можно загружать одновременно сразу несколько кадров и кодировать их параллельно. Таким образом можно загрузить видеокарту полностью и получить максимальную производительность даже для изображений небольшого размера. Поэтому скорость сжатия для серий небольших кадров будет близкой к тем результатам, которые получены для больших одиночных изображений. Такой режим работы для одновременной загрузки и сжатия нескольких изображений уже протестирован и будет включён в финальную версию кодека FVJPEG. Также хотелось бы отметить, что результаты, полученные на видеокарте GeForce GTX 580 для скорости сжатия изображений по алгоритму JPEG с потерями, превосходят по производительности все известные аппаратные решения по сжатию изображений на ПЛИС (FPGA) для того же самого алгоритма. Одни из самых быстрых систем сжатия изображений на ПЛИС по алгоритму JPEG предлагают следующие компании:
Сравнивая программный кодер на 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 ожидается в ближайшее время.
Cписок литературы:
Автор(ы) : Ф.Л. Серженко, к.ф.-м.н., В.Д. Подложнюк, компания "Фаствидео", Дубна
Внимание ! Использование любых текстовых или графических материалов(а так-же их фрагментов) с сайта http://www.telephototech.ru возможно с разрешения администрации сайта с обязательным указанием ссылок на первоисточник и авторов статей и публикаций ! |
|