Вопросы производительности кода OpenCL* и Intel® Quick Sync Video на Intel® HD Graphics 4000

Скачать статью

Performance Interactions of OpenCL* Code and Intel® Quick Sync Video on Intel® HD Graphics 4000 [Eng., PDF 488KB]

Введение

Разработчики видеоредакторов и других приложений, создающих или обрабатывающих видеокадры, и затем кодирующие их с помощью Intel® Quick Sync Video, могут столкнуться с затруднениями при попытках повысить производительность, применяя OpenCL* для переноса обработки кадров с центрального процессора на графический процессор Intel® HD Graphics. В этом документе поясняются причины таких затруднений и перечисляются нагрузки, для которых можно добиться повышения производительности, что позволяет разработчикам эффективнее использовать OpenCL.

 

Непредвиденная проблема

В рамках подготовки OpenCL для графических процессоров (GPU) Intel в преддверии выпуска процессоров Intel® Core™ 3-го поколения я оптимизировал несколько ядер OpenCL для редактирования видео. Я предполагал, что перенос некоторых задач по обработке эффектов видеоизображения с CPU на GPU повлечет существенное повышение производительности приложения.

В тестах ядра OpenCL действительно продемонстрировали более высокую производительность по сравнению с одним ядром CPU, применяющим тот же эффект к хорошо оптимизированному коду. В среднем обработка ускорилась в 3 раза, а для некоторых ядер было достигнуто 20-кратное ускорение по сравнению с эквивалентным кодом для CPU. Казалось, что я старался не напрасно: мне действительно удалось добиться более высокой скорости. После интеграции ядер OpenCL в приложение в некоторых нагрузках действительно стал заметен прирост скорости.

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

В чем же была причина?

 

Введение

Используемые приложение для редактирования видео отличалось высоким качеством кода и было прекрасно приспособлено для использования возможностей параллельных вычислений процессора. Кодирование видеоэффектов осуществлялось с помощью инструкций SIMD, а для обработки каждого видеокадра было использовано 4 потока (на 4-ядерном CPU). Приложение также использовало Intel Quick Sync Video для ускорения декодирования видео перед наложением видеоэффектов и для повторного кодирования видео после этого.

Для наиболее быстрой работы OpenCL обычно следует выделить один из четырех потоков для запуска ядер эффектов на GPU с помощью OpenCL, из-за чего количество потоков, обрабатывающих эффекты на CPU, уменьшается на один. Это считалось вполне приемлемой уступкой, поскольку при независимом тестировании ядра OpenCL на GPU обычно обрабатывали видео значительно быстрее, чем они поток CPU. Снижение производительности за счет исключения одного потока CPU из обработки видео должно было более чем с лихвой компенсироваться выигрышем в производительности потоков OpenCL на GPU.

Тем не менее, было обнаружено, что производительность не только не повышалась, но зачастую и снижалась при перемещении нагрузки по обработке эффектов из потоков CPU в потоки GPU с помощью OpenCL.

 

Использованные средства разработки

Для выявления проблемы и оптимизации приложения я использовал средства Intel® Visual Computing Developer Tools, которые можно бесплатно загрузить на сайте Intel® Developer Zone. Intel® Media SDK был использован для кодирования видео с аппаратным ускорением с помощью Intel Quick Sync Video. Пакет Intel® SDK for OpenCL* Applications был использован для разработки приложений OpenCL. Для оптимизации мультимедиа и графики я использовал Intel® Graphics Performance Analyzers (Intel® GPA).

 

Выявление проблемы

Прежде всего было отмечено, что наиболее заметная разница между нагрузками, демонстрировавшими преимущества OpenCL и нагрузкой, показавшей снижение производительности, была в видео, которое затем было закодировано в формат AVC (кодек H.264/MPEG4 Part 10) с помощью Intel Quick Sync Video. Также было отмечено, что без использования Intel® Quick Sync Video производительность приложения была значительно ниже, но в этом случае перемещение обработки эффектов из потоков CPU в GPU должно привести к повышению производительности - хотя итоговая производительность все равно была бы ниже, чем при использовании Intel Quick Sync Video.

После этого нужно было применить средства анализа производительности, чтобы лучше понять суть проблемы. Пакет Intel Graphics Performance Analyzers (Intel GPA) включает монитор производительности, который можно использовать для трассировки обработки программируемой графики. Данные трассировки можно анализировать в Intel® GPA Platform Analyzer, получая на выходе графики обработки на GPU за определенный отрезок времени. Количество и толщина вертикальных полосок на графиках грубо соответствует объему и длительности интервалов обработки на GPU. Также можно выделять области полосок, чтобы получать точную информацию об общем времени и времени обработки для выделенной области. Это дает возможность вполне точно измерять использование GPU.

На рис. 1 показана работа интегрированного в процессор графического ядра примерно за 2 секунды для типовой нагрузки: хорошо оптимизированный видеоэффект обрабатывается на 4 ядрах CPU, а кодирование видео в формат AVC (кодек H.264 part 10) также осуществляется силами CPU, без OpenCL и Intel Quick Sync Video.

Рис. 1Трассировка Intel GPA Performance Monitor. GPU не используется

 

Здесь видно крайне малое использование GPUОН (графический процессор, обрабатывающий задачи общего назначения), менее 1%. По всей вероятности, вся эта нагрузка - это обновление небольших анимационных элементов на экране (индикатор хода выполнения и т.п.).

На следующем рисунке показана такая же нагрузка, но с использованием Intel Quick Synch Video для кодирования в формат AVC. Строка «GPU Unknown» осталась практически без изменений, но появились три строки, связанные с обработкой кодирования видео. Строка «04: GPU: ENCODE» выполняется на операционных блоках встроенного графического ядра, как и строка «GPU: VPP». Последняя строка «06: GPU: ENCODE» представляет обработку кодирования на выделенном аппаратном устройстве, то есть речь идет об аппаратной оценке движения, а не о GPUОН.

Рис. 2Трассировка Intel GPA c кодированием Quick Synch Video

 

Важнейший для нас вывод из этого рисунка заключается в том, что кодирование видео не занимает все время обработки графики графическим процессором. Если объединить все строки, представляющие время выполнения GPUОН, в одну строку, то будет заполнено лишь около 40% общего времени выполнения - суммы активного времени выполнения GPU, измеренного с помощью Intel GPA. В строке «GPU EU Queue» показано время, когда задачи помещены в очередь для выполнения на GPU, но еще не выполняются, поскольку GPU занят. Пробелы в этой строке означают, что в очереди задач не осталось задач для GPU.

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

На следующем рисунке снова показаны 2 секунды этой же нагрузки, и по-прежнему используется Intel Quick Sync Video для кодирования всего видео, но также используется OpenCL на GPU GPU для реализации видеоэффектов. Три остальных потока CPU по-прежнему обрабатывают видеоэффект, но один (из четырех) поток CPU теперь перемещен для выполнения видеоэффекта на GPU. Это видно по второй строке - наблюдается высокая нагрузка на GPUОН.

Рис. 3Трассировка с обработкой эффектов OpenCL

 

Обратите внимание, что верхняя строка, «GPU EU Queue», практически целиком заполнена. Это указывает на то, что почти всегда есть задачи, ожидающие выполнения, поскольку вычислительные ресурсы GPUОН заняты почти полностью. Менее очевиден тот факт, что если объединить строки «GPU: Unknown», «GPU: Encode» и «GPU: VPP», также образуется практически целиком заполненная строка, то есть заполнены почти все операционные блоки GPUОН. Изменения с помощью Intel GPA показали использование GPUОН примерно на 95%, то есть на 55% выше, чем в первом случае. Таким образом, представляется, что мы добились успеха: мы используем вычислительные мощности GPU почти полностью. (Незначительная доля ресурсов GPUОН утрачивается вследствие избыточной работы по запуску потоков на GPU.)

Тем не менее, фактическая скорость обработки в этом случае оказалась приблизительно на 20% ниже. В последней строке на рис. 3 (GPU: ENCODE) в сравнении с рис. 2 также показано намного меньше полосок, соответствующих кодированию кадров видео. Скорость обработки кадров снизилась, поскольку GPU осуществляет кодирование всех кадров. (Обратите внимание, что зачастую можно определить скорость кадров в коде приложения. Этот показатель можно сочетать с данными о загрузке GPU, полученными с помощью Intel GPA, чтобы проверить среднее время обработки кодирования каждого кадра.)

 

Что произошло?

Наиболее очевидным является следующее объяснение: алгоритм обработки видеоэффектов на GPU работает медленнее, чем при выполнении на CPU. Но тестирование видеоэффекта в отдельности показало, что данный конкретный эффект, показанный на приведенных выше рисунках, выполняется приблизительно вдвое быстрее (с использованием всех операционных блоков GPUОН), чем один поток CPU. Таким образом, версия на GPU должна работать быстрее, чем замененный ею поток CPU.

Тем не менее, как было отмечено выше и показано на рис. 4, Intel Quick Sync Video занимает около 40% времени выполнения GPUОН - по 10% для каждого из 4 потоков CPU, обрабатывающих эффекты. Обработка эффектов на GPUОН добавляет к этому еще 55%. Следовательно, обработка эффектов на GPUОН должна происходить примерно вдвое быстрее, чтобы производительность хотя бы сравнялась с показателем, достигнутым при использовании потоков CPU. (Перемещение кодирования видео на CPU приведет к еще большему снижению скорости, поэтому мы не будем рассматривать такой вариант.)

Рис. 4Обработка эффектов с помощью CPU и GPU и кодирование видео со временем

Кроме того, кодирование может занимать разную долю времени операционных блоков. Если ограничивающим фактором было кодирование видео в операционных блоках, что может произойти при очень быстрой работе алгоритмов обработки эффектов на CPU, то кодирование может занять 100% времени операционных блоков GPU. Поскольку 4 потока параллельно обрабатывают видеоэффекты, среднее время создания одного кадра для кодирования равно 1/4 времени обработки эффекта на CPU. Следовательно, для того чтобы кодирование видео не стало абсолютным ограничивающим фактором, время обработки эффектов на CPU должно быть больше, чем четырехкратное время кодирования одного видеокадра.

Рис. 5

В случае, описанном выше в главе «Выявление проблемы», среднее время кодирования на GPUОН составляло около 5 мс (хотя этот показатель, разумеется, может изменяться в широких пределах в зависимости от параметров кодирования и других факторов). И если обработка видеоэффектов на CPU занимает меньше 20 мс (четырехкратное время кодирования, равное 5 мс), то общая скорость будет ограничиваться скоростью кодирования видео, и перенос обработки эффектов на GPUОН ни при каких обстоятельствах не приведет к повышению производительности. В описываемом приложении почти половина эффектов укладывалась в эту категорию.

Но это еще не конец. Наша цель - увидеть повышение производительности за счет применения GPUОН для обработки эффектов, например, повышение производительности на 25%. Величина в 25% означает, что за такой же промежуток времени должно быть закодировано 5 кадров. Следовательно, обработка эффектов одного кадра на CPU должна занимать по крайней мере впятеро больше времени, чем кодирование одного кадра на GPUОН (т.е. 25 мс, если время кодирования равно 5 мс).

Рис. 6

Кроме того, нужно оставить какое-то время для запуска обработки эффектов с помощью OpenCL на GPUОН. Впрочем, такие рассуждения становятся слишком сложными. Давайте рассмотрим несколько примеров и рассчитаем предполагаемое влияние на производительность.

 

Примеры переноса обработки эффектов с CPU на GPUОН

Вновь предположим, что время кодирования видео на GPUОН равно 5 мс, а время обработки эффектов на CPU - 30 мс. 25 мс займет кодирование 5 кадров (для достижения описанного выше увеличения скорости на 25%), для обработки эффектов на GPUОН остается 5 мс. Мы исходим из того, что один поток CPU занят, поэтому CPU создаст только 3 кадра за 30 мс, а значит для GPU остается 2 кадра. Если оставить 5% на издержки, то ядру OpenCL на GPUОН придется обработать один кадр примерно за 2 мс, то есть работать в 15 раз быстрее, чем такой же алгоритм работает на одном потоке CPU! Нельзя назвать это совсем уж невозможным, но добиться такого превосходства в скорости удается крайне редко.

Рис. 7

 

В рассматриваемом приложении скорость при использовании GPUОН вместо одного потока CPU возрастала в среднем в 3 раза. Давайте исходить из более реалистичных показателей: пусть время обработки эффектов на GPUОН равно 20 мс, а на CPU - 60 мс. За 60 мс на CPU будет закодировано 3 кадра, а на GPU - Х (икс) кадров, издержки времени выполнения GPUОН составляют около 5%. Чтобы узнать, сколько кадров видеоэффектов должны быть обработаны и закодированы на GPUОН за 60 мс, нужно найти Х, решив следующее уравнение:

60 мс = кадирование (5 мс/кадр)*(X+3 кадров) + эффекты (20 мс/кадр)*(X кадров GPU) + 60*0.05

Уравнение 1

 

Решением здесь будет X = 1.2 кадра обработки эффектов на GPUОН. Это означает, что вместо 4 кадров за 60 мс, с обработкой эффектов на GPUОН мы сможем получить (1,2 + 3) = 4,2 кадра. Повышение производительности составляет 5%.

Как добиться повышения производительности на 25%? В приведенном выше уравнении для этого потребуется Х=2, то есть один кадр заменяет один поток CPU, и еще один, чтобы получить 5 кадров вместо 4 за такой же отрезок времени. Общее время кодирования 5 кадров составит 25 мс (5 кадров по 5 мс). Сохраним такое же время обработки эффектов на CPU - 60 мс. Пусть Y будет временем обработки эффектов на GPUОН (а издержки составят 5%, то есть 3 мс). Новое уравнение будет выглядеть следующим образом:

60 ис = кодирование (5 мс/кадр)*(5 фреймов) + эффекты (Y мс/кадр)*(2 кадра) + 3 мс

Уравнение 2

 

Решение этого уравнение таково: Y (время обработки эффектов на GPUОН) = 16 мс/кадр. Следовательно, для ускорения приложения на 25% ядро OpenCL GPUОН должно работать в 3,75 раза быстрее, чем CPU. Это вполне осуществимо.

Можно ли ускорить приложение вдвое? Если исходить из того, что за 60 мс на CPU обрабатываются эффекты для 4 кадров, потребуется изменить второе уравнение таким образом, чтобы на выходе получалось 8 кадров, из которых 5 обрабатывает GPUОН, а 3 - CPU:

60 мс = кодирование (5 мс/кадр)*(8 кадров) + эффекты (Y мс/кадр)*(5 кадров) + 3 мс

Уравнение 3

 

В этом случае скорость обработки эффектов на GPUОН (в нашем уравнении - Y) равна 3,4 мс на один кадр, то есть в 17,6 раз быстрее CPU. Такое превосходство в скорости GPUОН над CPU достигается крайне редко.

Предположим, что время обработки эффектов на CPU равно 100 мс. При этом уравнение изменится следующим образом (издержки составляют 5%, то есть в данном случае 5 мс):

100 мс = кодирование (5 мс/кадр)*(8 кадров) + эффекты (Y мс/кадр)*(5 кадров) + 5 мс

Уравнение 4

 

В этом случае скорость обработки эффектов на GPUОН (в нашем уравнении - Y) равна 11 мс/кадр. Для удвоения производительности всего приложения GPUОН должен быть в 9,1 раз быстрее CPU. Это возможно, но добиться такого превосходства очень трудно.

Как видно из приведенных выше уравнений, чем больше время обработки эффектов на CPU превышает время кодирования видео на GPUОН, тем проще добиться повышения производительности за счет переноса обработки на GPUОН.

 

Нагружаем CPU

А что произойдет, если приложение не займет поток CPU при добавлении потока обработки эффектов на GPU? Это вполне возможно, поскольку для запуска ядер OpenCL на GPU и для ожидания завершения работы ядер требуется крайне мало времени CPU. Запуск обработки эффектов на всех наличных ядрах CPU повлечет некоторое увеличение времени отклика потоков OpenCL на GPUОН. Потоку эффектов на CPU может потребоваться завершить свой временной интервал, прежде чем поток GPU сможет отреагировать на завершение работы ядра и запустить следующее ядро, из-за чего будут менее эффективно задействованы операционные блоки GPU.

Возьмем в качестве основы уравнение 1, где производительность работы CPU равна 60 мс/кадр, а GPU - 20 мс/кадр. Приведенное ниже уравнение 5 (где Х - количество кадров, созданных на GPU) соответствует обработке эффектов в 4 потоках CPU. Для учета задержки в обслуживании ядер OpenCL добавлено 10% на издержки (6 мс):

60 мс = кодирование (5 мс/кадр)*(Х+4 кадров) + эффекты (20 мс/кадр)*(Х кадров GPU) + 6 мс

Уравнение 5

 

Если решить это уравнение, мы получим Х = 0,97, то есть около одного кадра на GPU. В этом случае за 60 мс вместо первоначальных 4,2 кадров будет обработано около 5 кадров. Рост производительности составляет 25% по сравнению с использованием только CPU и 19% по сравнению с уравнением 1, где мы исходили из полной занятости одного потока. Но обратите внимание, что такой выигрыш в скорости опирается на достаточно существенное - троекратное - превосходство GPUОН в скорости над CPU, и на то, что время обработки эффектов на CPU достаточно велико по сравнению с временем кодирования на GPUОН. Если бы время работы CPU составляло всего 30 мс, то уравнение выглядело бы так:

330 мс = кодирование (5 мс/кадр)*(Х+4 кадров) + эффекты (20 мс/кадр)*(Х кадров GPU) + 3 мс

Уравнение 6

 

Х = 0,25, то есть GPUОН обрабатывает эффекты для 0,25 кадров, а общий результат – 4,25 кадров, то есть выигрыш по производительности (по сравнению с использованием только CPU) поставляет лишь 6%. И хотя CPU по-прежнему обрабатывает эффекты, время обработки эффектов на CPU должно быть намного больше времени кодирования на GPU для получения сколько-нибудь заметного выигрыша по скорости.

 

Режим Intel Turbo

А теперь следует упомянуть один интересный фактор - принцип работы режима Turbo. В режиме Turbo, грубо говоря, один из компонентов - либо CPU, либо GPU - может работать существенно быстрее, если второй компонент не слишком загружен. Если CPU не имеет высокой нагрузки, то частота GPU может быть увеличена почти вдвое. Частота CPU также может быть увеличена (при невысокой нагрузке на GPU), но на меньшую величину. Одновременное увеличение частоты CPU и GPU невозможно из-за ограничений, налагаемых тепловым режимом работы процессора. Работа и CPU, и GPU на повышенной частоте приведет к перегреву чипа, в котором находятся оба этих компонента.

В режиме Turbo приведенные выше простые расчеты окажутся недействительными, особенно если CPU будет полностью загружен активными потоками при попытке ускорения работы приложения за счет GPUОН. Можно исходить из того, что наши расчеты несколько переоценивают потенциальное ускорение за счет добавления OpenCL в приложение, если расчеты основаны на отдельных оценках производительности CPU и GPU.

 

Выводы

Настройку производительности приложений с использованием OpenCL (с ускорением GPUОН) и Intel Quick Sync Video следует производить, помня о том, что эти процессы GPUОН будут занимать вычислительные ресурсы GPU. Из этого следует несколько выводов:

- Если 4 ядра процессора Intel Core 3-го поколения обрабатывают потоки, выдающие кадры интегрированному GPU Intel HD Graphics 4000 для кодирования видео, производительность не вырастет при переносе обработки с CPU на ядро OpenCL GPUОН, если время обработки на CPU меньше четырехкратного времени кодирования видео на GPU для одного кадра. Аналогичные правила действуют и для другого числа ядер. (Используйте Intel GPA для измерения времени кодирования видео на программируемых графических операционных блоках.)

- Время обработки одного кадра на CPU (на полностью загруженном 4-ядерном CPU) должно превышать 4-кратное время кодирования одного кадра на GPUОН, чтобы у GPUОН осталось достаточно времени для выполнения работы, перенесенной на ядро OpenCL. Время обработки на CPU должно в общем случае значительно превышать аналогичное время обработки на GPUОН, чтобы можно было получить ощутимый (25% или больше) прирост скорости. Чем дольше занимает обработка на CPU, тем проще добиться повышения производительности на GPUОН с помощью OpenCL.

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

- При кодировании Intel Quick Sync Video может потребоваться определенная обработка на GPU. Из-за этого уменьшится объем вычислительных ресурсов, доступный для обработки OpenCL на GPU, что, в свою очередь, затруднит повышение производительности за счет переноса вычислений с CPU на GPU.

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

Если принимать во внимание все эти факторы, разработчик сможет сэкономить немало времени при настройке производительности приложений, использующих кодирование Intel Quick Sync Video, да и любых других приложений, которым требуется распределять нагрузку между CPU и GPU. Измеряя время потоков CPU и используя Intel GPA Media Performance Analyzer для измерения времени существующей (Intel Quick Sync Video или иной) обработки на GPUОН, разработчик сможет быстро понять, повлечет ли перенос обработки с CPU на GPUОН Intel с использованием OpenCL какое-либо повышение производительности.

 

Дополнительные материалы

Intel® SDK для приложений на OpenCL*: www.intel.com/software/opencl

Intel® SDK для приложений на OpenCL* - Руководство оптимизации: /sites/landingpage/opencl/optimization-guide/index.htm

Intel GPA: www.intel.com/software/gpa

 

Для получения подробной информации о возможностях оптимизации компилятора обратитесь к нашему Уведомлению об оптимизации.