Рендерскрипт для растровой обрезки

Похоже, что BitmapRegionDecoder Android SDK использует Skia для декодирования части указанного растрового изображения. Под капотом для этого используется соответствующий код (jpeg, png и т. д.). Я ищу способы оптимизировать это с помощью Renderscript.

Можно ли определить функцию ядра Renderscript для игнорирования определенных данных при распределении ввода и сохранения остальных при распределении вывода? Я новичок в Renderscript, и большая часть функций ядра имеет тенденцию работать со всем набором входных данных.


person Vairavan    schedule 27.06.2017    source источник


Ответы (1)


Да, используйте LaunchOptions API, чтобы ограничить прямоугольник, над которым вы запускаете:

Script.LaunchOptions lo;
lo.setX(10, 100);
lo.setY(5, 20);
kernel.forEach(in, out, lo);

https://developer.android.com/reference/android/renderscript/Script.LaunchOptions.html

person sakridge    schedule 27.06.2017
comment
Спасибо, я попробовал, но это не удалось из-за несоответствия размеров для ввода и вывода. Я хотел, чтобы выходное распределение было только для того, что было необходимо (после обрезки). Вместо этого я нашел несколько советов по привязке ввода, и это сработало как шарм, потрясенный улучшениями производительности :-) - person Vairavan; 28.06.2017
comment
Да, вход/выход должен быть одинакового размера. Для другого размера сделайте, как вы говорите, используйте rs_allocation global для одного из них и используйте функции rsGetElementAt_*. - person sakridge; 28.06.2017
comment
Мало того, forEach в нужной области обрезки (выделение выходных данных) намного эффективнее, чем forEach во всем распределении входных данных и выборе желаемых значений, не так ли? Очень актуально для крошечного кропа на огромном изображении. - person Vairavan; 29.06.2017
comment
Есть ли способ получить статистику операции rs? Мне любопытно, какой процессор использовался (CPU, GPU или DSP). - person Vairavan; 04.07.2017
comment
Взгляните на профилировщик Qualcomm Trepn, который может отображать загрузку CPU/GPU во время прогона. Это может указать, какой процессор используется. - person sakridge; 11.07.2017
comment
Спасибо, отличный совет. В моем случае GPU вообще не используется, и все же rs помог в Snapdragon 810. Я предполагаю, что SIMD ARM помогает. Как только я запускаю rs, я замечаю, что все четыре процессора работают на постоянной частоте ~ 1,5 кГц, а оставшиеся 4 процессора снижаются до 0,5 кГц и остаются там до завершения сценария. - person Vairavan; 15.07.2017
comment
Пробовали добавить #pragma rs_fp_relaxed в свой код? Также убедитесь, что вы не используете функции типа double или rsDebug. - person sakridge; 15.07.2017
comment
То же самое с rs_fp_relaxed (без активности графического процессора), и я просто использую uint, uchar и не использую функции отладки. Есть ли какая-нибудь прагма, чтобы принудительно включить его в GPU, чтобы увидеть производительность? - person Vairavan; 16.07.2017
comment
Нет никакого способа заставить GPU из приложения. Возможно, ваше ядро ​​просто лучше работает на процессоре. Если вы можете поделиться более подробной информацией о вашем устройстве и вашем коде ядра, возможно, я смогу лучше понять, почему. - person sakridge; 19.07.2017
comment
uchar4 __attribute__((kernel)) урожая(uint32_t x, uint32_t y) { int inX = x + startX; int inY = y + startY; вернуть rsGetElementAt_uchar4 (inAllocation, inX, inY); } - person Vairavan; 19.07.2017
comment
Я попробовал это на Nexus 6P и в основном привязал выделение ввода, startX и startY — это верхние левые координаты желаемой области обрезки. - person Vairavan; 19.07.2017
comment
Ваше ядро, по сути, является копией, которая сильно привязана к памяти. Поскольку GPU и CPU имеют доступ к основной памяти с одинаковой скоростью, я ожидаю, что в этом случае скорость между CPU и GPU будет очень схожей. - person sakridge; 19.07.2017
comment
Да, но не приведет ли использование нескольких ядер графического процессора к более быстрой копии, чем простое использование 4 ядер ЦП? Даже в случае процессора кажется, что используются только 4 ядра, а оставшиеся 4 просто остаются на частоте 0,5 кГц. - person Vairavan; 20.07.2017
comment
На самом деле, и процессор, и графический процессор в наши дни достаточно быстры, чтобы максимально использовать пропускную способность памяти SoC. Дополнительные ядра графического процессора будут просто ждать в системе памяти, ожидая возврата данных. Кроме того, как долго работает ваше ядро? Время нравится: time.start(); kernel_ForEach(): rs.finish() time.end(). time = end - start; - person sakridge; 20.07.2017
comment
Интересно, что для кадрируемой области размером 9290772 пикселя rs заняло 28 миллисекунд. 22 миллисекунды для 2840178 пикселей и 16 для 369600 пикселей. Я думаю, это больше, чем я могу просить от RS. - person Vairavan; 22.07.2017