Как стать автором
Обновить

Комментарии 27

А что насчет предыдущего поколения? GTX980?
На GeForce GTX 980 кодирование в JPEG с теми же параметрами для картинки 4К даёт 1,3 мс. Всем желающим по запросу могу в личку прислать документ с бенчмарками.

А можете ли вы его выложить в конце статьи? Я думаю многим будет интересно посмотреть.

Версия на английском тут. Вариант на русском сделаю и выложу. Скорее всего, завтра.
Ссылка на документ с бенчмарками теперь есть в конце статьи.
у вас опенсорс или покупать?
если опенсорс, то где скачать, если покупать, то расскажите про условия покупки и ценник
Это не опенсорс. Демо SDK и документацию могу выслать по запросу. Цены и условия обсуждать здесь не стоит.
да, конечно.

Если не сложно, то на max@erlyvideo.org или могу я вам написать.
Завтра пришлю.
Применяться это будет исключительно в решениях на заказ и собственных скоростных видеокамерах вашей компании? Кажется, этот кодек мог бы быть самостоятельным продуктом.
С одной стороны — это самостоятельный продукт, с другой — часть нашего SDK для обработки изображений на видеокартах NVIDIA. Скоростные видеокамеры — это лишь один из многих вариантов возможных приложений. Сейчас большинство наших заказчиков занимаются 3D и VR, но есть и масса других приложений, в том числе и с камерами.
Интересно было бы посмотреть результаты на OpenCL + APU, по идее там копировать данные не нужно.
Мне было бы тоже интересно на это посмотреть, но я не встречал бенчмарков для кодека JPEG на OpenCL. Если найдёте, пожалуйста расскажите или дайте ссылку.
Радеоновский драйвер подменяет родную либу Винды на свой декодер, если кому-то интересно это проверить. Почему JPEG, кстати? Если для VR, то логичнее сразу кодировать в fixed bitrate формат, который из коробки читается видеокартой. Даже если сжатие меньше, производительность непосредственно VR возрастет. А скачивание миллионов картинок обратно на хоста это какой-то странный юзкейс, в этом случае производительность обработки ограничена половиной скорости PCI-E.
Радеоновский драйвер подменяет родную либу Винды на свой декодер, если кому-то интересно это проверить.
Давайте говорить точно: какую либу подменяют, на какой именно декодер, какая у этого декодера производительность, какие у такого кодера порядок сжатия и качество. Без этого любое сравнение вряд ли будет корректным. Тут всё очень конкретно: алгоритм, визуальное качество, степень сжатия, скорость работы. Интересно, что и как делает радеоновский драйвер.

Почему JPEG, кстати? Если для VR, то логичнее сразу кодировать в fixed bitrate формат, который из коробки читается видеокартой. Даже если сжатие меньше, производительность непосредственно VR возрастет.
Наши заказчики выбирают JPEG, потому что его можно очень быстро декодировать, визуальное качество для них приемлемое при коэффициенте сжатия порядка 10. Среди требований заказчиков никогда не встречал необходимость fixed bitrate формата. Некоторые алгоритмы жмут лучше, но у них со скоростью проблемы. JPEG – это компромисс, как это всегда и бывает при сжатии с потерями.

Математика тут простая. Обычно заказчики заранее создают все необходимые изображения. Далее задача состоит в том, чтобы 12-Мпикс картинку показывать на мониторе или в очках с частотой 100 Гц или более. Это значит, что в секунду нам нужно закачать в память видеокарты 12 Мпикс*3*100 = 3600 МБайт. Если скорость шины PCI-Express x16 равна 12 ГБ/с, то один кадр можно передать за 3 мс и это не проблема. Проблема состоит в том, как с SSD передать 3600 МБайт данных в секунду в видеокарту. Мы все изображения заранее сжимаем в 10 раз, после чего с передачей 360 МБ/с нет никаких проблем. Переслать эти данные можно за 0,3 мс, декодировать за 4 мс. В сумме получается больше, чем 3 мс, но меньше 10 мс (100 Гц).

А скачивание миллионов картинок обратно на хоста это какой-то странный юзкейс, в этом случае производительность обработки ограничена половиной скорости PCI-E.
Для 3D и VR не нужно качать миллионы картинок на хост, движение идёт в обратном направлении. Нужно с хоста качать картинки в видеокарту.
Я полагаю, люди перебрали кучу вариантов и понимают, что делают, но решение реально неочевидное. Кодируешь всё каким-нибудь ASTC и получаешь примерно те же числа (передача чуть дольше, распаковка чуть быстрее), но переносимо.
Вы полагаете или знаете? Если знаете, пожалуйста покажите расчёты, хотя бы приблизительные. В чём именно состоит решение? Почему получаются те же числа?
https://upload.wikimedia.org/wikipedia/en/c/c4/Original_Image_before_ASTC_compression.jpg
https://en.wikipedia.org/wiki/File:Detail_of_ASTC_compressed_image.png
При битрейте 4 (шестикратное сжатие) бита на пиксель лично я не нашел каких-то искажений мелких деталей (увеличил оригинал в пеинте до 300%, оригинал изначально jpeg, так что черт его знает, насколько на самом деле есть разница). Отсюда считывание с диска будет занимать где-то в 1.8 раз дольше, чем в случае с JPEG. Я не знаю, насколько быстрее будет распаковка, но этот формат был специально разработан для поддержки в железе, в видеокартах есть специальные устройства с отдельным кешом как раз для работы с текстурами. В 10 мс всё должно влезать вообще без проблем.
Как следует из этой ссылки, формат ASTC был разработан и принят в качестве официального расширения для OpenGL и OpenGL ES в 2012 году, т. е. совсем недавно. Карточки AMD его поддерживают, а у NVIDIA такая поддержка есть только в Kepler и в мобильных чипах на Maxwell. Не очень это похоже на общепринятый стандарт.
JPEG и Motion JPEG – это давно признанные и широко распространённые стандарты. Поэтому можно просто сделать AVI, который будет работать в любом плеере и который легко разобрать на кадры, оправить их в видеокарту и там декодировать. Для таких решений важна также универсальность, которая есть в случае с JPEG.
Не очень это похоже на общепринятый стандарт.

… Поэтому мы берем дорогущую квадру на, видимо, раскаленном Ферми там, где справится затычка с гигом памяти. Ладно, шучу. Я сразу сказал, что раз делают так, а не иначе, значит были причины.
я не очень понял, как вы от кодека (jpeg) перешли к паршивому и устаревшему контейнеру avi, который далеко не везде работает (это вообще атавизм из мира виндузятников). Какой кодек вы собираетесь класть в avi?
Кодек джипег выполняет работу по быстрому кодированию кадров на видеокарте. А укладка сжатых изображений в контейнер не является задачей для CUDA, с этим хорошо справляется FFmpeg. Так получилось, что в большинстве задач для видеокамер наши заказчики просили AVI, поэтому мы так и сделали. Обычно заказчик сам подключает FFmpeg и получает нужный ему контейнер.
Это очень круто, но почему выбрали именно CUDA? Вместо OpenCL! Вы же 'намертво' привязали свою разработку к одному вендору железа, и не самому лучшему по соотношению цена-скорость.
Или все на столько плохо и оптимизация требуется на самом низком уровне, и красивые переносимые решения нужных скоростей не дают?
OpenCL это тоже на данный момент привязка намертво, потому что NVIDIA (и Apple на Маках) поддержку методично убивает, Knights Landing от Интела для обработки изображений менее эффективен, а для FPGA нужно писать совсем другой код. Полноценно работать можно только с GCN, и только на Линуксе с Виндой. Теперь вы знаете, почему эпоха GPGPU для конечных пользователей не настанет никогда.
Вы совершенно правы — как только требуется оптимизация на низком уровне, то в любом случае получается непереносимое решение. И уже не важно, это CUDA или OpenCL.

С нашей точки зрения это лучший вендор, потому что кроме цены и скорости (тут идеала нет ни у кого) есть ещё среда разработки, с которой у NVIDIA всё очень хорошо. А ещё есть мобильные решения, доля рынка видеокарт и пр. Да просто найти программиста по OpenCL — это тоже большая проблема. Мы видим больше плюсов у NVIDIA.
Спасибо за статью, приятно видеть, что Cuda используется в коммерческих проектах. Сам сейчас работаю в академической среде, во многом с кудой.
У меня вопрос: у вас есть ссылки на доступное описание алгоритма сжатия JPEG? Интересно оценить сложность задачи. Судя по вашей производительности в 30 ГБ/c это compute-bound метод?
И еще один: вы не интересовались новой связкой P100 + IBM Power + NVlink? Чтобы устранить задержки от PCI-E?
Описание алгоритма JPEG можно найти в Википедии или в моей предыдущей статье (ссылка есть в начале текста). Раньше этот алгоритм считался вычислительно сложным, теперь уже можно полагать, что это не совсем корректно. Мне кажется, что даже при такой производительности это memory-bound случай. Большинство улучшений по сравнению с предыдущими версиями были получены благодаря более эффективному использованию разделяемой памяти и регистров, сам алгоритм не изменился. Также очевидна проблема с достижением более полной загрузки видеокарты. Видно, что при увеличении размера данных производительность растёт, и это логично. Для получения большей скорости нужно ещё больше данных, хотя количество вычислений для заданного размера картинки остаётся прежним. Если сразу кодировать несколько изображений (это называется режим пачки), то ухудшится латентность (увеличится время отклика), а производительность станет ещё выше. Мы этот режим ещё не сделали, пока скорости и без него хватает, а в задачах реального времени обычно нужна минимальная латентность. Но режим пачки есть в наших планах, мы его обязательно сделаем.

Устранять задержки от PCI-E можно разными способами. Скорость у PCI-E довольно высокая, поэтому желательно сразу оценить, какой выигрыш возможен и стоит ли игра свеч. Для максимально быстрого получения данных от видеокамер можно сделать GPUDirect, т. е. модифицировать драйвер так, чтобы он по DMA отправлял данные сразу в видеокарту. Мы так сделали, но результат разочаровал. Сэкономили миллисекунду, а это оказалось совсем мало, поэтому больше так не делаем.
Ещё можно организовать стримы (CUDA Streams), которые обеспечат загрузку новых изображений во время расчётов с текущим кадром. Так очень часто и делают, но это приводит к дополнительному расходу памяти. Если совместить стримы с пачкой, то получится ещё быстрее.

Про связку P100 + IBM Power + NVlink ничего сказать не могу.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории