Почему этот образ обработки изображений Google Renderscript работает медленнее на графическом процессоре в Nexus 5

Я хотел бы поблагодарить Стивена за очень быстрый ответ в предыдущем посте. Это следующий вопрос для этого сообщения. Почему очень простой Renderscript работает в три раза медленнее в GPU, чем в CPU

Моя платформа dev выглядит следующим образом

Development OS: Windows 7 32-bit Phone: Nexus 5 Phone OS version: Android 4.4 SDK bundle: adt-bundle-windows-x86-20131030 Build-tool version: 19 SDK tool version: 22.3 Platform tool version: 19 

Чтобы оценить производительность графического процессора Renderscript и понять общий способ сделать код быстрее Renderscript, я сделал следующий тест.

Я проверил код из проекта Google с открытым исходным кодом Android, используя тег android-4.2.2_r1.2. Я использовал этот тег просто потому, что тестовый образец ImageProcessing недоступен в более новой версии.

Затем я использовал проект в разделе «base \ tests \ RenderScriptTests \ ImageProcessing» в тесте. Я записал производительность запуска кода на GPU, а также CPU, и производительность приведена ниже.

  GPU CPU Levels Vec3 Relaxed 7.45ms 14.89ms Levels Vec4 Relaxed 6.04ms 12.85ms Levels Vec3 Full N/A 28.97ms Levels Vec4 Full N/A 35.65ml Blur radius 25 203.2ms 245.60ms Greyscale 7.16ms 11.54ms Grain 33.33ms 21.73ms Fisheye Full N/A 51.55ms Fisheye Relaxed 92.90ms 45.34ms Fisheye Approx Full N/A 51.65ms Fisheye Approx Relaxed 93.09ms 39.11ms Vignette Full N/A 44.17ms Vignette Relaxed 8.02ms 46.68ms Vignette Approx Full N/A 45.04ms Vignette Approx Relaxed 8.20ms 43.69ms Convolve 3x3 37.66ms 16.81ms Convolve 3x3 Intrinsics N/A 4.57ms ColorMatrix 5.87ms 8.26ms ColorMatrix Intrinsics N/A 2.70ms ColorMatrix Intinsics Grey N/A 2.52ms Copy 5.59ms 2.40ms CrossProcess(using LUT) N/A 5.74ms Convolve 5x5 84.25ms 46.59ms Convolve 5x5 Intrinsics N/A 9.69ms Mandelbrot N/A 50.2ms Blend Intrinsics N/A 21.80ms 

N / A в таблице вызвано либо полной точностью, либо rs intrinsics не работает на графическом процессоре. Мы видим, что среди 13 алгоритмов, работающих на GPU, 6 из них работают на GPU медленнее. Поскольку такой код был написан Google, я бы подумал, что это явление стоит того, чтобы его исследовать. По крайней мере, «я предполагаю, что код будет работать быстрее на GPU», я видел из Renderscript, и GPU здесь не выполняется.

Я исследовал некоторые из алгоритмов в списке, я хотел бы упомянуть два.

В Vignette производительность на графическом процессоре намного лучше, я обнаружил, что это было использовано, вызывая несколько функций в rs_cl.rsh. Если я прокомментирую эти функции, процессор будет работать быстрее (см. Мой предыдущий вопрос в верхней части для крайнего случая). Поэтому возникает вопрос, почему это происходит. В rs_cl.rsh большинство функций связаны с математикой, например, exp, log, cos и т. Д. Почему такая функция работает на GPU намного быстрее, это потому, что реализация этих функций на самом деле очень параллельна или просто потому, что реализация Версия работает на GPU лучше, чем версия работает на CPU?

Другим примером является conv3x3 и conv5x5. Хотя в этом тестовом приложении есть еще более умная реализация, чем версия Google, я думаю, что эта реализация Google, конечно же, неплохая. Он пытается минимизировать операцию добавления и использует некоторую функцию упрощения от rs_cl.rsh, например convert_float4 (). Поэтому, с первого взгляда, я предполагаю, что он будет работать быстрее на GPU. Однако он работает намного медленнее (на Nexus 4 и 5 с использованием GPU Qualcomm). Я думаю, что этот пример очень репрезентативен, поскольку в реализации алгоритм должен получить доступ к пикселям рядом с текущим пикселем. Такая операция довольно распространена во многих алгоритмах обработки изображений. Если реализация, подобная 2D-свертке, не может быть выполнена быстрее в GPU, я подозреваю, что многие другие алгоритмы будут страдать одинаково. Было бы высоко оценено, если вы сможете определить, где проблема, и предложить некоторые способы ускорения таких алгоритмов.

Более общий вопрос заключается в том, что, учитывая результат теста, который я показал, я хотел бы спросить, какие критерии следует соблюдать, чтобы получить более высокую производительность и как можно меньше избежать ухудшения производительности. В конце концов, цель исполнения – вторая по важности цель Renderscript, и я считаю, что переносимость RS неплоха.

Спасибо!

На этот вопрос действительно два ответа.

1: Не верьте шумихе относительно графических процессоров. Для некоторых рабочих нагрузок они быстрее. Однако для многих рабочих нагрузок разница небольшая или отрицательная. У вас есть как минимум 2 разных типа процессора, не беспокойтесь о том, какой из них можно использовать, только беспокоитесь, если производительность – это то, что вы хотите.

2: Для настройки производительности я бы действительно сосредоточился на алгоритме и избегал медленных операций. Примеры:

  • Предпочитайте, чтобы float удваивался, когда float обеспечивает адекватную точность.

  • Используйте RS_FP_RELAXED, когда вам не требуется соответствие IEEE-754

  • Предпочитайте умножение на деление

  • Используйте native_ * (например: native_powr) вместо полных точных подпрограмм, где точность адекватна

  • Используйте rsGetElementAt_ * over rsSample или rsGetElementAt. Типичная версия get быстрее, чем обычно, и во многих случаях происходит намного быстрее, чем rsSample.

  • Нагрузки от глобальных скриптов обычно быстрее, чем нагрузки из rs_allocation. Предпочитают глобальные константы ядра.

3: Сегодня проблемы производительности с глобальными нагрузками на пути к графическому процессору Nexus (4,5,7v2). Они будут улучшены с помощью обновлений.