Android 渲染脚本永远不会在 GPU 上运行



正如标题所说。

我有一个我想使用的并行图像创建/处理算法。这是一种柏林噪声实现。

// Logging is never used here
#pragma version(1)
#pragma rs java_package_name(my.package.name)
#pragma rs_fp_full
float sizeX, sizeY;
float ratio;
static float fbm(float2 coord)
{ ... }
uchar4 RS_KERNEL root(uint32_t x, uint32_t y)
{
float u = x / sizeX * ratio;
float v = y / sizeY;
float2 p = {u, v};
float res = fbm(p) * 2.0f;   // rs.: 8245 ms, fs: 8307 ms; fs 9842 ms on tablet
float4 color = {res, res, res, 1.0f};
//float4 color = {p.x, p.y, 0.0, 1.0};  // rs.: 96 ms
return rsPackColorTo8888(color);
}

相比之下,当我通过纹理四边形上的片段着色器在 GPU 上实现它时,这个精确的算法以至少 30 fps 的速度运行。

运行 RenderScript 的开销应最大为 100 毫秒,这是我通过返回 x 和 y 规范化坐标制作简单位图计算得出的。

这意味着如果它使用 GPU,它肯定不会变成 10 秒。

我使用RenderScript的代码:

// The non-support version gives at least an extra 25% performance boost
import android.renderscript.Allocation;
import android.renderscript.RenderScript;
public class RSNoise {
private RenderScript renderScript;
private ScriptC_noise noiseScript;
private Allocation allOut;
private Bitmap outBitmap;
final int sizeX = 1536;
final int sizeY = 2048;
public RSNoise(Context context) {
renderScript = RenderScript.create(context);
outBitmap = Bitmap.createBitmap(sizeX, sizeY, Bitmap.Config.ARGB_8888);
allOut = Allocation.createFromBitmap(renderScript, outBitmap, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_GRAPHICS_TEXTURE);
noiseScript = new ScriptC_noise(renderScript);
}
// The render function is benchmarked only
public Bitmap render() {
noiseScript.set_sizeX((float) sizeX);
noiseScript.set_sizeY((float) sizeY);
noiseScript.set_ratio((float) sizeX / (float) sizeY);
noiseScript.forEach_root(allOut);
allOut.copyTo(outBitmap);
return outBitmap;
}
}

如果我将其更改为 FilterScript,使用此帮助 (https://stackoverflow.com/a/14942723/4420543),在支持库的情况下,我会变得更糟几百毫秒,在不支持库的情况下会差大约两倍。精度不影响结果。

我还检查了堆栈溢出上的所有问题,但其中大多数都已经过时了,我也在其他几个新设备中使用 nexus 5(7.1.1 操作系统版本)进行了尝试,但问题仍然存在。

那么,RenderScript 什么时候在 GPU 上运行呢?如果有人能给我一个运行GPU的RenderScript的例子就足够了。

您可以尝试使用 rs_fp_relaxed 而不是rs_fp_full运行它吗?

#pragma rs_fp_relaxed

rs_fp_full将强制脚本在 CPU 上运行,因为大多数 GPU 不支持全精度浮点运算。

我可以同意你的猜测。

在 Nexux 7(2013 年,JellyBean 4.3)上,我分别编写了一个渲染脚本和一个过滤器来计算著名的曼德布洛特集合。 与执行相同操作的 OpenGL 片段着色器(所有 32 位浮点数)相比,脚本的速度大约慢3 倍。我假设OpenGL使用GPU,而renderscript(和filterscript!)则不使用。

然后,我将相机预览转换(NV21格式-> RGB)分别与渲染脚本,过滤器脚本和ScriptIntrinsicYuvToRGB进行了比较。在这里,Intrinsic 比自写脚本快约 4 倍。 同样,我认为渲染脚本和过滤器脚本之间的性能没有差异。在这种情况下,我假设自写脚本仅在内部函数使用 GPU 的情况下再次使用 CPU(也是?

最新更新