Android - RenderScript - SDK 21 中的性能下降
Android - RenderScript - Performance drop in SDK 21
我正在开发一个需要复杂的 Photoshop 类型混合效果的项目。我正在使用自定义 RenderScript
脚本来解决这个问题。
我一直在 Samsung Galaxy S4
设备 运行ning Kitkat 上测试它,一切都运行得很好而且非常快。
然后我尝试在 Nexus 5 运行ning Lollipop 上测试它,我注意到性能突然下降.
我开始对代码中的各个部分进行计时,以查看哪些部分速度变慢,并得出以下结论:
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
我很好奇为什么在本应更强大的设备上创建 Allocation
对象并销毁 RenderScript
对象时性能会突然下降,而在 OS 哪个应该更高级。
我可以针对 API 21 OS 做些什么来使这些方法 运行 更快吗?
有没有人遇到过这个问题或者可以重现它?
我应该注意到脚本的实际 运行ning(即 ScriptC.forEach
方法)运行 在两个设备上都非常快/OS .另外,我使用的是原生 RenderScript
APIs 而不是任何支持库。
如有任何意见,我们将不胜感激。
编辑:
的 Github 中复制了 Androids Lollipop-release 源代码中的相关行
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);
}
注意当目标 SDK 高于 17 时,Allocation 是如何默认使用 USAGE_SHARED
标志创建的。可能是这些额外的标志导致了问题吗?我应该改用 USAGE_GRAPHICS_TEXTURE
标志吗?
编辑 2
按照 R. Jason Sam 的建议,当 Nexus 5 连接到我的计算机时,我 运行 以下脚本:
adb shell setprop debug.rs.default-CPU-driver 1
在此之后,运行上述函数的时间明显加快(分别为 ~30-40 毫秒和 20-50 毫秒)。仍然不如棒棒糖之前的设备那么快,但在可接受的性能范围内 运行ge.
我对这个解决方案的唯一问题是,除非我不明白,否则不能被视为解决方案,因为它需要我在每个有问题的设备上调用这个脚本,然后再 运行 应用程序就可以了。
我可以在我的代码中做些什么来模拟这个 adb 调用吗?
最终编辑
好的,问题似乎源于我每次调用使用 RenderScript 执行混合效果的函数时都创建了一个新的 RenderScript 对象。
我做了一些代码重构,现在,我不再在每次调用 effect 方法时创建一个新的 RenderScript 对象,而是每次都重复使用相同的对象。在 Lollipop 设备上创建 RenderScript 对象的第一次创建仍然需要更长的时间,但现在问题得到缓解,因为我在多个方法调用中继续重复使用相同的对象。
我会将其添加为答案。
在 Api 18 (USAGE_SHARED) 中添加了一个分配类型。如果您强制 Renderscript 复制位图后备内存(而不是就地使用它),这可能会导致差异。
Allocation tmpOut = Allocation.createFromBitmap(mRenderContext, result, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SHARED);
问题似乎源于我每次调用使用 RenderScript
.
执行混合效果的函数时都在创建一个新的 RenderScript
对象
我做了一些代码重构,现在,我不再在每次调用 effect 方法时都创建一个新的 RenderScript
对象,而是每次都重复使用同一个对象。 RenderScript
对象的第一次创建在 Lollipop 设备上创建仍然需要更长的时间,但现在问题得到缓解,因为我在多个方法调用中继续重复使用相同的对象。
一旦我确定我不再需要它以确保没有内存泄漏,我一定会在共享 RenderScript
对象上调用 destory()
。
根据 this post,重用 RenderScript
对象而不是每次创建一个新对象似乎是公平的做法,但我很高兴听到来自其他人关于他们在此事上的经验。遗憾的是,网上没有太多关于此主题的文档,但到目前为止,一切似乎都在多个设备/OS 上运行良好。
我正在开发一个需要复杂的 Photoshop 类型混合效果的项目。我正在使用自定义 RenderScript
脚本来解决这个问题。
我一直在 Samsung Galaxy S4
设备 运行ning Kitkat 上测试它,一切都运行得很好而且非常快。
然后我尝试在 Nexus 5 运行ning Lollipop 上测试它,我注意到性能突然下降.
我开始对代码中的各个部分进行计时,以查看哪些部分速度变慢,并得出以下结论:
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
我很好奇为什么在本应更强大的设备上创建 Allocation
对象并销毁 RenderScript
对象时性能会突然下降,而在 OS 哪个应该更高级。
我可以针对 API 21 OS 做些什么来使这些方法 运行 更快吗?
有没有人遇到过这个问题或者可以重现它?
我应该注意到脚本的实际 运行ning(即 ScriptC.forEach
方法)运行 在两个设备上都非常快/OS .另外,我使用的是原生 RenderScript
APIs 而不是任何支持库。
如有任何意见,我们将不胜感激。
编辑:
的 Github 中复制了 Androids Lollipop-release 源代码中的相关行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);
}
注意当目标 SDK 高于 17 时,Allocation 是如何默认使用 USAGE_SHARED
标志创建的。可能是这些额外的标志导致了问题吗?我应该改用 USAGE_GRAPHICS_TEXTURE
标志吗?
编辑 2
按照 R. Jason Sam 的建议,当 Nexus 5 连接到我的计算机时,我 运行 以下脚本:
adb shell setprop debug.rs.default-CPU-driver 1
在此之后,运行上述函数的时间明显加快(分别为 ~30-40 毫秒和 20-50 毫秒)。仍然不如棒棒糖之前的设备那么快,但在可接受的性能范围内 运行ge.
我对这个解决方案的唯一问题是,除非我不明白,否则不能被视为解决方案,因为它需要我在每个有问题的设备上调用这个脚本,然后再 运行 应用程序就可以了。
我可以在我的代码中做些什么来模拟这个 adb 调用吗?
最终编辑
好的,问题似乎源于我每次调用使用 RenderScript 执行混合效果的函数时都创建了一个新的 RenderScript 对象。
我做了一些代码重构,现在,我不再在每次调用 effect 方法时创建一个新的 RenderScript 对象,而是每次都重复使用相同的对象。在 Lollipop 设备上创建 RenderScript 对象的第一次创建仍然需要更长的时间,但现在问题得到缓解,因为我在多个方法调用中继续重复使用相同的对象。
我会将其添加为答案。
在 Api 18 (USAGE_SHARED) 中添加了一个分配类型。如果您强制 Renderscript 复制位图后备内存(而不是就地使用它),这可能会导致差异。
Allocation tmpOut = Allocation.createFromBitmap(mRenderContext, result, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SHARED);
问题似乎源于我每次调用使用 RenderScript
.
RenderScript
对象
我做了一些代码重构,现在,我不再在每次调用 effect 方法时都创建一个新的 RenderScript
对象,而是每次都重复使用同一个对象。 RenderScript
对象的第一次创建在 Lollipop 设备上创建仍然需要更长的时间,但现在问题得到缓解,因为我在多个方法调用中继续重复使用相同的对象。
一旦我确定我不再需要它以确保没有内存泄漏,我一定会在共享 RenderScript
对象上调用 destory()
。
根据 this post,重用 RenderScript
对象而不是每次创建一个新对象似乎是公平的做法,但我很高兴听到来自其他人关于他们在此事上的经验。遗憾的是,网上没有太多关于此主题的文档,但到目前为止,一切似乎都在多个设备/OS 上运行良好。