[英]Android - RenderScript - Performance drop in SDK 21
I'm developing a project which requires complex Photoshop type blend effects. 我正在开发一个需要复杂的Photoshop类型混合效果的项目。 I am using custom
RenderScript
scripts to solve this. 我使用自定义
RenderScript
脚本来解决这个问题。
I've been testing it on a Samsung Galaxy S4
device running Kitkat , and everything works great and very quickly. 我一直在运行Kitkat的
Samsung Galaxy S4
设备上进行测试,一切都运行得非常快。
I then tried testing it on a Nexus 5 running Lollipop , and I noticed a sudden drop in performance. 然后我尝试在运行Lollipop的Nexus 5上测试它,我注意到性能突然下降。
I started timing separate sections in the code to see which parts slow down, and came up with this: 我开始计算代码中的不同部分以查看哪些部分减速,并想出了这个:
Allocation.createFromBitmap
- Runtime on Kitkat - ~5-10 millisec
- Runtime on Lollipop - ~100-150 millisec
mRenderScript.destory()
- Runtime on Kitkat - ~1-3 millisec
- Runtime on Lollipop - ~60-100 millisec
I'm curious as to why there is a sudden drop in performance when creating Allocation
objects and destroying RenderScript
objects on a device which should be stronger, and on an OS which should be more advanced. 我很好奇为什么在创建
Allocation
对象并破坏应该更强大的设备上的RenderScript
对象以及应该更高级的操作系统时性能突然下降。
Is there anything I can do specific to API 21 OS's which can make these methods run faster? 我能为API 21操作系统做些什么可以使这些方法运行得更快吗?
Has anyone even encountered this issue or can reproduce it? 有没有人甚至遇到过这个问题或者可以重现它?
I should note that the actual running of the script (ie, the ScriptC.forEach
method) runs very fast on both devices / OS's. 我应该注意,脚本的实际运行(即
ScriptC.forEach
方法)在两个设备/操作系统上都运行得非常快。 Also, I am using the native RenderScript
APIs and not any support libraries. 此外,我使用的是本机
RenderScript
API,而不是任何支持库。
Any input would be appreciated. 任何输入将不胜感激。
Edit: 编辑:
I copied here the relevant row from Androids Lollipop-release source code in Github of Allocation.java 我在这里复制了Allocation.Lava的 Github中Androids Lollipop发布源代码中的相关行
static public Allocation createFromBitmap(RenderScript rs, Bitmap b) {
if (rs.getApplicationContext().getApplicationInfo().targetSdkVersion >= 18) {
return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
USAGE_SHARED | USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE);
}
return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
USAGE_GRAPHICS_TEXTURE);
}
Notice how when the target SDK is higher than 17, the Allocation is created by default with the USAGE_SHARED
flag. 请注意,当目标SDK高于17时,默认情况下会使用
USAGE_SHARED
标志创建分配。 Could it be that these extra flags are causing the problem? 可能是这些额外的标志导致了问题吗? Should I be using the
USAGE_GRAPHICS_TEXTURE
flag instead? 我应该使用
USAGE_GRAPHICS_TEXTURE
标志吗?
Edit 2 编辑2
Following R. Jason Sam 's advice, I ran the following script when the Nexus 5 was connected to my computer: 根据R. Jason Sam的建议,当Nexus 5连接到我的电脑时,我运行了以下脚本:
adb shell setprop debug.rs.default-CPU-driver 1
After this, the runtime of the said functions is significantly faster (~30-40 millisec & 20-50 millisec respectively). 在此之后,所述功能的运行时间明显更快(分别为~30-40毫秒和20-50毫秒)。 Still not as fast as pre-lollipop devices, but within the accepted performance range.
仍然没有预棒棒糖设备快,但在可接受的性能范围内。
My only issue with this solution is that, unless I don't understand something, cannot be considered a solution, since it would require me to call this script on every problematic device before running the app on it. 我解决这个问题的唯一问题是,除非我不理解某些东西,否则不能被视为解决方案,因为它需要我在每个有问题的设备上调用此脚本,然后才能在其上运行应用程序。
Is there anything I can do in my code which can simulate this adb call? 我的代码中有什么可以模拟这个adb调用吗?
Final Edit 最终编辑
Okay, so it seems like the issue stemmed from the fact that I was creating a new RenderScript object on each time I called the function which performed the blend effect using RenderScript. 好吧,似乎这个问题源于我每次调用使用RenderScript执行混合效果的函数时创建一个新的RenderScript对象。
I did some code refactoring and now, instead of creating a new RenderScript object on each call to the effect method, I reuse the same one each time. 我做了一些代码重构,现在,不是在每次调用效果方法时创建一个新的RenderScript对象,我每次都重用相同的一个。 The 1st creation of the RenderScript object still takes much longer to create on Lollipop devices, but the problem is mitigated now since I continue to reuse the same object throughout multiple method calls.
在Lollipop设备上创建RenderScript对象的第一次创建仍然需要更长的时间,但由于我在多个方法调用中继续重用相同的对象,因此问题现在得到了缓解。
I will add this as an answer. 我将添加此作为答案。
It seems like the issue stemmed from the fact that I was creating a new RenderScript
object on each time I called the function which performed the blend effect using RenderScript
. 似乎这个问题源于我每次调用使用
RenderScript
执行混合效果的函数时都在创建一个新的RenderScript
对象。
I did some code refactoring and now, instead of creating a new RenderScript
object on each call to the effect method, I reuse the same one each time. 我做了一些代码重构,现在,不是在每次调用效果方法时创建一个新的
RenderScript
对象,我每次都重用相同的一个。 The 1st creation of the RenderScript
object still takes much longer to create on Lollipop devices, but the problem is mitigated now since I continue to reuse the same object throughout multiple method calls. 在Lollipop设备上创建
RenderScript
对象的第一次创建仍然需要更长的时间,但由于我在多个方法调用中继续重用相同的对象,因此问题现在得到了缓解。
I make sure to call destory()
on the shared RenderScript
object once I am sure I no longer need it to ensure there are no memory leaks. 一旦我确定不再需要它来确保没有内存泄漏,我确保在共享的
RenderScript
对象上调用destory()
。
According to this post, it seems that it's fair practice to reuse RenderScript
objects rather than creating a new one each time, but I would be glad to hear input from other people regarding their experience on the matter. 根据这篇文章,似乎重复使用
RenderScript
对象而不是每次都创建一个新对象是公平的做法,但我很高兴听到其他人对他们在这件事上的经验的意见。 It's a shame there's not much documentation on this topic online, but so far, everything seems to be working well across multiple devices / OS's. 遗憾的是,网上没有太多关于这个主题的文档,但到目前为止,一切似乎都在多个设备/操作系统中运行良好。
There was an Allocation Type that was added in Api 18 (USAGE_SHARED). 在Api 18(USAGE_SHARED)中添加了分配类型。 If you are forcing Renderscript to copy the bitmap backing memory (instead of using it in place) that might account for the difference.
如果您强制Renderscript复制位图支持内存(而不是使用它)可能会解释差异。
Allocation tmpOut = Allocation.createFromBitmap(mRenderContext, result, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SHARED);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.