RenderScript 自定义 ScriptC 比 Intrinsics 慢

Posted

技术标签:

【中文标题】RenderScript 自定义 ScriptC 比 Intrinsics 慢【英文标题】:RenderScript custom ScriptC slower than Intrinsics 【发布时间】:2015-07-30 15:40:16 【问题描述】:

我创建了一个非常简单的灰度脚本,它需要比内在模糊渲染更多的时间。为什么?

灰度.rs:

#pragma version(1)
#pragma rs java_package_name(com.nanotapsoft.cartooncamera)

#pragma rs_fp_relaxed

uchar4 __attribute__((kernel)) grayscale(uchar4 pixelIn, uint32_t x, uint32_t y) 
    uchar grayscale = (pixelIn.r + pixelIn.g + pixelIn.b) / 3;  // simple average
    //uchar grayscale = pixelIn.r * 0.299 + pixelIn.g * 0.587 + pixelIn.b * 0.114;

    uchar4 pixelOut;
    pixelOut.a = pixelIn.a;
    pixelOut.r = grayscale;
    pixelOut.g = grayscale;
    pixelOut.b = grayscale;

    return pixelOut;

在java中调用:

    t1 = System.currentTimeMillis();

    iBmp.copyFrom(tmpbmp);

    blurscript.setInput(iBmp);
    blurscript.forEach(oBmp);

    oBmp.copyTo(tmpbmp);

    t2 = System.currentTimeMillis();
    System.out.println("Blur: " + (t2-t1));

    t1 = System.currentTimeMillis();

    iBmp.copyFrom(tmpbmp);
    grayscaleScript.forEach_grayscale(iBmp, oBmp);
    oBmp.copyTo(tmpbmp);

    t2 = System.currentTimeMillis();
    System.out.println("Grayscale: " + (t2-t1));

模糊平均为 12 毫秒,灰度平均为 28 毫秒

【问题讨论】:

比较时使用的模糊半径是多少? 我使用 blurscript.setRadius(5f);但是无论我设置什么半径,灰度应该花费更少的时间,因为它是一个更简单的过程。还是灰度脚本有更优化的代码? 在这种情况下,听起来内置的内在内核确实使用了一些我们其他人无法使用的特殊优化。您的灰度内核似乎有点快,人们会期望其性能优于模糊。 也许吧。我做了一个基于 YUV 输入的简单灰度脚本,它比这个快 5 倍。 分配的来源是什么?相机预览有没有机会? 【参考方案1】:

对于那些想要更快的灰度渲染脚本的人,如果您使用 YUV 数据,您可以将速度提高 5 倍:

#pragma version(1)
#pragma rs java_package_name(com.nanotapsoft.cartooncamera)

#pragma rs_fp_relaxed

rs_allocation ain;
rs_allocation aout;

rs_script grayscaleYUVScript;

void root(const uchar *v_in, uchar4 *v_out, const void *usrData, uint32_t x, uint32_t y) 

    uchar yp = rsGetElementAtYuv_uchar_Y(ain, x, y) & 0xff;
    v_out->r = yp;
    v_out->g = yp;
    v_out->b = yp;
    v_out->a = 0xff;


void filter()

    rs_allocation ignored;
    #if !defined(RS_VERSION) || (RS_VERSION < 14)
        rsForEach(grayscaleYUVScript, ignored, aout, 0);
    #else
        rsForEach(grayscaleYUVScript, ignored, aout);
    #endif

对于我使用的第一个脚本的相同输入大小,此脚本的平均执行时间约为 7 毫秒。

【讨论】:

以上是关于RenderScript 自定义 ScriptC 比 Intrinsics 慢的主要内容,如果未能解决你的问题,请参考以下文章

Android RenderScriptRenderScript 简介 ③ ( RenderScript 发布和运行 | RenderScript 脚本 )

RenderScript多输入参数

RenderScript Intrinsics 高斯模糊

使用 Renderscript 启动选项裁剪图像数据

RenderScript在Android 6上崩溃

为啥 Google 选择 RenderScript 而不是 OpenCL [关闭]