强制默认CPU实现时,RenderScript的速度提高了10倍



我已经在RenderScript中实现了一个CNN,在上一个问题中描述了这一问题。基本上,在运行时

adb shell setprop debug.rs.default-CPU-driver 1

Nvidia Shield和Nexus 7都有10倍的加速。平均计算时间从50毫秒左右到5毫秒,测试应用程序从50帧/秒左右到130帧或更多。有两种卷积算法:

(1) 移动内核
(2) 来自RenderScriptIntrinsicsBLAS的im2col和GEMM。

两者都经历了类似的加速。问题是:为什么会发生这种情况,这种效果能否以可预测的方式从代码中实例化?关于这方面的详细信息在哪里有?

编辑:

根据下面的建议,我验证了finish()和copyTo()的使用,下面是过程的分解。报告的加速是在调用copyTo()之后,但没有finish()。取消对finish()的计数会增加约1ms的时间。

double forwardTime = 0;
long t = System.currentTimeMillis();
//double t = SystemClock.elapsedRealtime(); // makes no difference
for (Layer a : layers) {
    blob = a.forward(blob);
}
mRS.finish();   // adds about 1ms to measured time 
blob.copyTo(outbuf);
forwardTime = System.currentTimeMillis() - t;​

也许这是无关的,但在NVIDIA Shield上,我在启动时收到一条错误消息,当使用adb shell setprop-debug.rs.default-CPU-driver 1 运行时,该消息会消失

E/Renderscript: rsAssert failed: 0, in vendor/nvidia/tegra/compute/rs/driver/nv/rsdNvBcc.cpp

我现在正在将compileSdkVersion、minSdkVersion和targetSdkVersion设置为23,buildToolsVersion为"23.0.2"。平板电脑会自动更新到最新的Android版本。不确定我需要设置的最小目标,并且仍然有ScriptIntrinsicsBLAS可用。

我在所有脚本中都使用#pragma rs_fp_related。Allocations都使用默认标志
这个问题也有类似的情况,但事实证明OP在每一轮计算中都在创建新的Script对象。我什么也不做,所有的脚本和分配都是在初始化时创建的。

原来的帖子注释掉了mRS.finish()。我想知道这里是不是这样。

为了正确地对RenderScript进行基准测试,我们应该等待挂起的异步操作完成。通常有两种方法:

  1. 使用RenderScript.finish()。使用debug.rs.default-CPU-driver 1时效果良好。它也适用于大多数GPU驱动程序。然而,某些GPU驱动程序确实将此视为NOOP
  2. 使用Allocation.copyTo()或其他类似的API访问Allocation的数据,最好是最终输出Allocation。这实际上是一个技巧,但它适用于所有设备。请注意,copyTo操作本身可能需要一些时间,并确保将其考虑在内

5ms看起来很可疑,可能是真的,这取决于实际的算法。但是,当您添加finish()或copyTo()时,是否仍然是这种情况,值得仔细检查。

这确实很奇怪。事实上,你在两个设备上都得到了相同的结果,并且使用了两个非常不同的conv层实现,这表明基准测试或时序本身还有其他问题,而不是CPU/GPU执行的差异,因为事情很少是决定性的。

我建议验证copyTo()的输出是否始终相同。设置一个logcat输出,比如说,从每个层的输出分配返回的浮点数组中的前10个(和最后10个!)值,以确保所有实现和执行模式在每个层真正正确、平等地处理数据。

根据您的设置,我之前提到的数据复制开销也可能会超过计算时间本身,您所看到的只是一个不幸的影响,因为从一个地方或另一个地方复制数据可能需要或多或少的时间。尝试增加conv内核大小或计数(使用伪/随机值,只是为了测试),使计算更加复杂,从而抵消计算与数据加载时间的平衡,看看这会对结果产生什么影响。

如果其他一切都失败了,可能只是GPU真的因为某种原因需要更长的时间,尽管很难找到原因。有些事情需要检查。。。您使用的数据类型和大小是什么?您是如何将数据加载/写入分配的?您是否已经在使用#pragma rs_fp_related来设置浮点精度?您为分配用途设置了哪些标志(例如allocation.usage_SCRIPT|allocation.usage_GRAPHICS_TEXTURE)?

至于你的最后一个问题,不幸的是,关于具体优化问题的详细RS文档仍然很少。。。我认为在这里询问SO仍然是目前可用的最佳资源之一:)

相关内容

最新更新