Android - RenderScript - SDK 21中的性能下降 [英] Android - RenderScript - Performance drop in SDK 21

查看:291
本文介绍了Android - RenderScript - 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 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆