Performance Primitives for Multimedia Processing and Coding Fairmont Hotel, San Jose | 10.01.2009 | Frank Jargstorff, Anton Obukhov Что такое NPP? • Библиотека функций (примитивов) на языке C, созданных для работы на CUDA • API соответствует IPP (Intel Integrated Performance Primitives) – Подмножество функциональности IPP – Фокус на обработке изображений и видео • Быстрее IPP до 32х раз • Свободно распространяется – Бинарные файлы скомпилированные под Windows, Linux (32- и 64 бит) и Mac OS X • Release 1.0: Available at – http://www.nvidia.com/npp Взгляд сверху

• Цели и задачи NPP • Как использовать NPP? – Примеры • Что внутри NPP? – Типы данных – Функции • Производительность – Масштабирование – Сравнение с IPP Цели и задачи NPP

• Простота использования – не трубует знаний об архитектуре GPU – легко интегрируется в проекты • легко добавляется в существующие проекты • работает в связке с другими библиотеками • Выполнение на GPU с поддержкой CUDA • Высокая производительность – освобождает разработчика от оптимизационного ада • Инкапсуляция в алгоритмические блоки (Примитивы) – Решение задач путем построения цепей из примитивов Простота использования

• Идентично реализует Intel IPP API – IPP широко используется в программах с большим запросом к производительности – удобно спроектированный API • Использует CUDA “Runtime API” – указатели NPP API являются указателями в пространстве глобальной памяти GPU – управление памятью предоставлено программисту • Основана на указательной арифметике; API без оверхеда – взаимодействие на уровне указателей с кодом (C for CUDA) и библиотеками (cuFFT, cuBLAS, etc.) – максимально простой «фреймворк», минимум структур и объектов – прозрачность и отсутствие неявных операций Пример кода // allocate source image // allocate host source image int sp; int hp; Ipp8u * pSI = ippiMalloc_8u_C1(w, h, &sp); Ipp8u * pHI = ippiMalloc_8u_C1(w, h, &hp); // fill with some image content // fill with some image content testPattern_8u_C1(pSI, sp, w, h); testPattern_8u_C1(pHI, hp, w, h); // allocated device source image int sp; Npp8u * pSI = nppiMalloc_8u_C1(w, h, &sp); // copy test image up to device cudaMemcpy2D(pSI, sp, pHI, hp, w, h, cudaMemcpyHostToDevice); // allocated destination image // allocate device result image int dp; int dp; Ipp8u * pDI = ippiMalloc_8u_C1(w, h, &dp); Npp8u * pDI = nppiMalloc_8u_C1(w, h, &dp); // Filter mask and achor // Filter mask and achor IppiSize mask = {5, 5}; NppiSize mask = {5, 5}; IppiPoint anchor = {0, 0}; NppiPoint anchor = {0, 0}; IppiSize ROI = {w - mask.width + 1, NppiSize ROI = {w - mask.width + 1, h - mask.height + 1}; h - mask.height + 1}; // run box filter // run box filter ippiFilterBox_8u_C1R(pSI, sp, pDI, dp, nppiFilterBox_8u_C1R(pSI, sp, pDI, dp, ROI, mask, anchor); ROI, mask, anchor); Что такое NPP?

• Функции обработки изображений – подмножество группы “IPPI” – ~300 функций • Ограниченный набор поддерживаемых типов – 8u_C1, 8u_C4, 8u_AC4 – 32s_C1, 32f_C1 • Полный набор функций конвертации форматов Что такое NPP? • Data exchange & initialization • Filter Functions – Set, Convert, CopyConstBorder, Copy, – FilterBox, Row, Column, Max, Min, Dilate, Transpose, SwapChannels Erode, SumWindowColumn/Row • Arithmetic & Logical Ops • Geometry Transforms – Add, Sub, Mul, Div, AbsDiff – Resize , Mirror, WarpAffine/Back/Quad, WarpPerspective/Back/Quad • Threshold & Compare Ops • Statistics – Threshold, Compare – Mean, StdDev, NormDiff, MinMax, • Color Conversion Histogram, SqrIntegral, RectStdDev – RGB To YCbCr (& vice versa), ColorTwist, • Computer Vision LUT_Linear – Canny Edge Detector • JPEG – DCTQuantInv/Fwd, QuantizationTable Производительность

• Сравнение с IPP – Методология проведения измерений • Масштабирование – С ростом размера задачи – С ростом числа процессоров • Результаты тестирования производительности Методология проведения измерений

• На каждый примитив приходится ряд тестов (функциональных и производительных): – запуск каждого теста не менее 10 раз – каждый запуск делается с одинаковыми данными и параметрами – время пересылки данных не учитывается • Производительность замеряется единой бенчмаркой – ~2500 тестов производительности – большинство тестов производительности повторяют функциональный тест • комбинации невыровненных указателей и необычных ROI • комбинации различных входных и конфигурационных параметров • размер входного изображения 720p и 2000x2000 Масштабирование с ростом размера задачи (1) • Примитив: ippi/nppiAbsDiff_32f_C1R – вычисляет абсолютную разность двух одноканальных float фреймов попиксельно и записывает результат в третий фрейм – сложность проблемы растет линейно 25 CPU Linear Algorithm • Ожидаемый результат 20 GPU 15 – линейный со сдвигами OCPU & OGPU

и наклонными SCPU & SGPU 10 Time

– OCPU < OGPU , SCPU > SGPU 5 Problem size • Где находится точка пересечения? 0 Масштабирование с ростом размера задачи (2) Intel Core i7 Extreme Edition i7-965 3.2 GHz, 4 (8) Core, 8MB Level 3 Cache • Начальный размер 1024x4 0.07 Nehalem AbsDiff_32f_C1R (16kB) 0.06 1 Thread • Конечный размер 1024x204 GTX 285 0.05 (~800kB) 0.04

• Пересечение: ms 0.03 – CPU slow: 48 lines = 48kPixel (4Byte) = 192kB 0.02 – CPU fast: 108 line = 0.01 108kPixel (4Byte) = 432kB Lines in Image (1024 x N) – 720p: 720 x 1280 = 0 900kPixel Масштабирование с ростом размера задачи (3) • Увеличиваем размер задачи 2.5 до 1024 x 4096 пикселей AbsDiff_32f_C1R

• Сегмент по оси линий X: 2 [1000, 3000] 1.5 – 1000 lines -> 4MByte image Nehalem 1 Thread – 3 images -> 12MByte working ms 1 set Geforce GTX 285 – 8MB level 3 cache size 0.5 • GPU масштабируется линейно Lines in Image (1024 x N) 0

• Ассимптотически GPU ~7.5x 4

300 448 744 152 596 892

1188 1484 1632 1928 2224 2372 2668 3112 3408 3556 3852 1336 1780 2076 2520 2816 2964 3260 3704 4000 быстрее 1040 Масштабирование с ростом числа процессоров (1) • Контролировать занятость ядер 0.6 GPU напрямую проблематично nppiAbsDiff_32f_C1R Geforce 9800 GTX+ • Сравним на 2-х разных GPU: 0.5 – Geforce 9800 GTX+: 16 SMs, 738MHz => 11808 Geforce GTX 285 0.4 – Geforce GTX 285: 30 SMs, 648MHz => 19440

– (16 * 738) / (30 * 648) = 11808/19440 = 0.6 0.3

• Соотношение на макс. размере: Time [ms] Time – 9800 GTX: 4.8ms 0.2 – GTX 285: 2.6ms 0.1 – 2.6/4.8 = 0.54 Lines in Image (1024 x N)

• GPU соответствует 0

4

164 324 644 964 804

теоретическим ожиданиям по 484

1124 1444 1604 1924 2084 2404 2724 2884 3204 3364 3684 4004 1284 1764 2244 2564 3044 3524 3844 масштабированию на всем диапазоне размеров задачи Масштабирование с ростом числа процессоров (2)

• ippSetNumThreads(n) для 0.09 Nehalem ippiAbsDiff_32f_C1R управления числом ядер 0.08 1 Thread Nehalem • Для больших размеров задач 0.07 2 Threads Nehalem 0.06 память становится основным 4 Threads узким местом на CPU 0.05 Nehalem 8 Threads 0.04

• Ожидали 4 линии на графике [ms] Time 0.03 • На практике примитив AbsDiff 0.02 не масштабируется с ростом 0.01 числа ядер даже для Lines in Image (1024 x N) маленьких размеров задачи 0 4 20 36 52 68 84 100 116 132 148 164 180 196 Масштабирование с ростом числа процессоров (3)

2.5 • Полный спектр размеров Nehalem 1 ippiAbsDiff_32f_C1R Thread изображений на CPU 2 Nehalem 2 Threads – Неясно как выбирать Nehalem 4 число нитей для 1.5 Threads Nehalem 8 достижения Threads 1 максимальной [ms] Time

производительности 0.5

• Не масштабируется с Lines in Image (1024 x N) 0

ростом числа ядер 4

164 324 484 644 804 964

1124 1284 3044 3204 3364 3524 3684 3844 4004 1444 1604 1764 1924 2084 2244 2404 2564 2724 2884 Результаты (1)

• Результаты усреднены 12 NPP Performance Suite Grand Totals по 2800 NPP тестам производительности 10

– каждый тест замеряет 8 npp и ipp 6 – размеры изображений

720p и 2k x 2k 4 • NPP оптимизации: Relative Agregate Speed 2 – нет оптимизации под процессор 0 Core2Duo t=1 Core2Duo t=2 Nehalem t=1 Nehalem t=8 Geforce 9800 Geforce GTX GTX+ 285 – нет вставок на ассемблере и т.п. Результаты (2)

Коэффициент ускорения сильно колеблется в зависимости от примитива – После устранения 0.5% выбросов на границах интервала – Для средних размеров входных данных: • Минимальное ускорение: 0.35x (т.е. CPU в 2.8x быстрее) • Максимальное ускорение: 27.1x – Для крупных размеров входных данных: • Минимальное ускорение : 0.26x (т.е. CPU в 3.8x быстрее) • Максимальное ускорение : 31.9x Результаты (3)

• Интересные факты: * Исключение: некоторые – NPP is 1.0 release статистические функции используют атомарные операции архитектуры 1.1 – был разработан за 6 месяцев – без процессорно-специфической оптимизации* • all code compiled for compute 1.0 or 1.1 – оптимизация большинства функций затрагивает только работу с глобальной памятью • Intel Core i7 vs. GTX 285 – немного разные поколения (GTX 285 – архитектура 1.5-летней выдержки) • Значит, есть пространство для оптимизации Результаты по категориям

• Mid vs. High – в каждой категории прирост Speedup by Category для high end карт 14

незначителен 12 • 8u types 10 9800 GTX+ vs. 8 – трудны для GPU Core2Duo (Midrange) Nehalem vs. GTX 296

Speedup 6 • 8u_C1 (Highend) 4 – затруднены объединенные 2 запрсы к памяти, больше 0 вычислений в кернеле 32f 8u_C4 8u_C1 2k x 2k Category – малые типы удобны IPP (L2) Итог • NPP – легок в интеграции – предоставляет существенный прирост производительности по сравнению с x86 – 300 функций • Производительность GPU/NPP – легкость масштабирования по размеру задач и числу процессоров – неэффективен для работы с малыми изображениями • Ограничения – нужны больше функций, типов данных и оптимизаций на разных уровнях Вопросы?

• Рассмотрите использование NPP в своем приложении! • Предоставьте отзыв: – чего не хватает в NPP – что в NPP работает недостаточно быстро – другие пожелания • По любым вопросам, связанным с NPP обращайтесь: – Frank Jargstorff (fjargsto@.com) – Anton Obukhov ([email protected]) – Ryan Prescott ([email protected]) Video Codecs on GPU Fairmont Hotel, San Jose | 10.01.2009 | Anton Obukhov Предпосылки Задача транскодирования видео нуждается в ускорении как никогда:

Кодирование hi-res видео Мобильные и портативные занимает десятки часов на устройства обладают современных десктопах нераскрытой вычислительной мощью Эволюция аппаратного ускорения

Without PureVideo™ HD High CPU Utilization

Bitstream Inverse Motion Processing Deblocking Transform Compenstation CAVLC CABAC

Geforce 7 Series Reduced CPU Utilization

Bitstream Inverse Motion Processing Deblocking Transform Compenstation CAVLC CABAC

Geforce 8 Series Minimal CPU Utilization

Bitstream Inverse Motion Processing Deblocking Transform Compenstation CAVLC CABAC Кодирование видео на NVIDIA GPU Средства: • SW H.264 кодек спроектированный для платформы CUDA – Baseline profile – Main profile – High profile Интерфейсы: • C library (NVCUVENC) • Direct Show API • Win7 MFT Декодирование видео на NVIDIA GPU Средства: • HW аппаратное ускорение – H.264 – VC1 – MPEG2 • SW MPEG2 декодер спроектированный для платформы CUDA Интерфейсы: • C library (NVCUVID), HW & SW • DXVA and Win7 MFT, HW only • VDPAU library, HW only Обработка видео на NVIDIA GPU Средства: • SW библиотека пре- и пост-обработки (designed for CUDA) – Noise Reduction – Deinterlacing – Polyphase Scaling – Color Processing – Deblocking – Detail enhance Интерфейсы: • VMR/EVR API Польза от декодирования на GPU ~100% разгрузка при декодировании 3 основных стандартов

Bitstream Processing Inverse Motion Deblocking H.264 CAVLC Transform Compenstation High CPU Utilization CABAC

Bitstream Without Processing Inverse Motion Deblocking VC-1 CAVLC Transform Compenstation NVIDIA GPU CABAC

Bitstream Processing Inverse Motion MPEG-2 CAVLC Transform Compenstation CABAC

Bitstream Processing Inverse Motion Deblocking Minimal CPU Utilization H.264 CAVLC Transform Compenstation CABAC

Bitstream Processing Inverse Motion Deblocking VC-1 CAVLC Transform Compenstation CABAC

Bitstream Processing Inverse Motion MPEG-2 CAVLC Transform Compenstation CABAC Производительность кодирования

CPU Encode GPU Encode 60.00 51.50 49.72 50.57 50.00 45.00 42.30 40.03 40.00 35.59

30.00 24.15 19.74 20.39

20.00 17.82 17.25 frames persecond frames

10.00

0.00 riverbed tractor sunflower 1080i2997_stockholm_ter 1080i2997_mobcal_ter pedestrian_area Frame size: 1080p Platform: 3.2 GHz quad core Nehalem, GeForce GTX 280 (128 core) GPU CPU encoder is MainConcept GPU encoder is NVIDIA H.264 CUDA encoder. Использование в жизни

Некоторые коммерческие приложения для транскодирования видео при помощи CUDA • Badaboom • Nero Move it • CyberLink PowerDirector • Loilo SuperLoiloscope • Тысячи их! Мысли вслух

• Как насчет и ? • Что происходит на системах multi-GPU? Мысли вслух

• Как насчет и ? – Linux: только декодирование с VDPAU – Mac OSX: QuickTime API Мысли вслух

• Что происходит на системах multi-GPU? – NVIDIA H.264 encoder поддерживает системы dual- GPU Мысли вслух

• Multi-GPU – обыденность • Программирование Multi-GPU систем само по себе нетривиально Мысли вслух

 N  CUDA предоставляет jobs GPU 0  K  доступ к каждому из   установленных GPU GPU 1 Work (N jobs) Как заставить их работать над одной задачей одновременно? GPU K-1 Мысли вслух

Создание программных средств для аппаратного ускорения транскодирования видео является приоритетной задачей Webinar 10/28/2009 9:00 AM - 11:00 AM PDT • Программирование Multi-GPU • Приложения к кодированию видео https://www2.gotomeeting.com/register/628549827 Вопросы?

?

E-mail: [email protected] “Introducing a new Multi-GPU framework” webinar, 10/28/2009 9:00 AM - 11:00 AM PDT https://www2.gotomeeting.com/register/628549827