简体   繁体   English

Android - RenderScript - SDK 21中的性能下降

[英]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. 我一直在运行KitkatSamsung Galaxy S4设备上进行测试,一切都运行得非常快。

I then tried testing it on a Nexus 5 running Lollipop , and I noticed a sudden drop in performance. 然后我尝试在运行LollipopNexus 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM