Android - RenderScript - SDK 21中的性能下降 [英] Android - RenderScript - Performance drop in SDK 21
问题描述
我正在开发一个需要复杂的Photoshop类型混合效果的项目。我使用自定义 RenderScript
脚本来解决这个问题。
我一直在<$ c $上测试它c>三星Galaxy S4 设备运行 Kitkat ,一切运行良好且非常快。
然后我尝试了测试它在 Nexus 5 上运行 Lollipop ,我注意到性能突然下降。
我开始计时分开代码中的部分以查看哪些部分变慢,并提出了这个:
Allocation.createFromBitmap
- 运行时在Kitkat上 - ~5-10 millisec
- Lollipop上的运行时间 - ~100-150 millisec
mRenderScript.destory()
- Kitkat上的运行时间 - ~1-3毫秒
- Lollipop上的运行时间 - 约60-100 millisec
我很好奇为什么那里在创建分配
对象并在设备上销毁 RenderScript
对象时性能突然下降应该更强,并且一个应该更先进的操作系统。
我能为API 21 OS做些什么可以让这些方法运行得更快吗?
有有人甚至遇到过这个问题或者可以重现它吗?
我应该注意脚本的实际运行情况(即 ScriptC.forEach
方法)在两个设备/操作系统上都运行得非常快。此外,我使用原生的 RenderScript
API而不是任何支持库。
任何输入都将不胜感激。
编辑:
我在这里复制了Androids Lollipop发布源的相关行代码在Github的 Allocation.java
static public Allocation createFromBitmap(RenderScript rs,Bitmap b){
if(rs.getApplicationContext() .getApplicationInfo()。targetSdkVersion> = 18){
返回createFromBitmap(rs,b,MipmapControl.MIPMAP_NONE,
USAGE_SHARED | USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE);
}
返回createFromBitmap(rs,b,MipmapControl.MIPMAP_NONE,
USAGE_GRAPHICS_TEXTURE);
}
注意目标SDK高于17时,分配是如何创建的默认使用 USAGE_SHARED
标志。可能是这些额外的标志导致了问题吗?我应该使用 USAGE_GRAPHICS_TEXTURE
标志吗?
编辑2
关注 R. Jason Sam的建议,当Nexus 5连接到我的电脑时,我运行了以下脚本:
adb shell setprop debug.rs.default-CPU-driver 1
此后,所述函数的运行时间显着更快(分别为~30-40毫秒和20-50毫秒)。仍然没有预先棒棒糖设备快,但在可接受的性能范围内。
我唯一的解决方案是,除非我不明白,否则不能被认为是一个解决方案,因为它需要我在每个有问题的设备上调用此脚本,然后才能在其上运行应用程序。
我的代码中有什么我可以做的可以模拟此adb电话吗?
最终修改
好的,所以看来就像这个问题源于我每次调用使用RenderScript执行混合效果的函数时创建一个新的RenderScript对象。
我做了一些代码重构而现在,我不是在每次调用效果方法时创建一个新的RenderScript对象,而是每次都重复使用相同的对象。在Lollipop设备上创建RenderScript对象的第一次创建仍然需要更长的时间,但现在问题已经减轻,因为我在多个方法调用中继续重用相同的对象。
我将添加此作为答案。
这个问题似乎源于我正在创建一个新的 RenderScript
每次调用使用 RenderScript
执行混合效果的函数时的对象。
我做过一些代码重构现在,而不是在每次调用效果方法时创建一个新的 RenderScript
对象,我每次都重复使用相同的对象。在Lollipop设备上创建 RenderScript
对象的第一次创建仍然需要更长的时间,但是现在问题得到缓解,因为我继续在多个方法调用中重用相同的对象。 / p>
我确保在共享的 RenderScript $ c $上调用
destory()
c>对象一旦我确定我不再需要它以确保没有内存泄漏。
根据这个帖子,似乎重用 RenderScript
对象似乎是公平的做法而不是每次创建一个新的,但我很高兴听到其他人关于他们在这件事上的经验的意见。遗憾的是,网上没有太多关于这个主题的文档,但到目前为止,一切似乎都在多个设备/操作系统上运行良好。
I'm developing a project which requires complex Photoshop type blend effects. I am using custom RenderScript
scripts to solve this.
I've been testing it on a Samsung Galaxy S4
device running Kitkat, and everything works great and very quickly.
I then tried testing it on a Nexus 5 running Lollipop, and I noticed a sudden drop in performance.
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.
Is there anything I can do specific to API 21 OS's which can make these methods run faster?
Has anyone even encountered this issue or can reproduce it?
I should note that the actual running of the script (i.e., the ScriptC.forEach
method) runs very fast on both devices / OS's. Also, I am using the native RenderScript
APIs and not any support libraries.
Any input would be appreciated.
Edit:
I copied here the relevant row from Androids Lollipop-release source code in Github of Allocation.java
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. Could it be that these extra flags are causing the problem? Should I be using the USAGE_GRAPHICS_TEXTURE
flag instead?
Edit 2
Following R. Jason Sam's advice, I ran the following script when the Nexus 5 was connected to my computer:
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). 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?
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.
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. 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.
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
.
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. 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.
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.
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. 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.
这篇关于Android - RenderScript - SDK 21中的性能下降的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!