Android NDK - 多线程正在减慢渲染速度

Posted

技术标签:

【中文标题】Android NDK - 多线程正在减慢渲染速度【英文标题】:Android NDK - Multithreading is slowing down rendering 【发布时间】:2014-03-27 02:09:01 【问题描述】:

我有一个带有 C++ 库的 android 应用程序,它使用 pthread 分解渲染任务。这适用于运行 Android 4+ 的设备。

假设我有一个 100 x 100 的元素数组,我在其中重复执行 CPU 密集型处理。目前,我将数组分成四个 25 x 100 元素块并将其交给四个 Posix 线程(来自一个停滞的、预先创建的线程池)。这使得 ios 和桌面 Mac 上的速度提高了近 4 倍,但结果比 Android 下的单线程慢。

因此,相同的代码成功地用于在 iOS 或桌面 Mac 上加快应用程序的速度,但在 Android 中,它通常会使其更慢。

我已经对其进行了一些测试,并且在使用多线程时只有相当大的数据垃圾会加速。如果整个过程(所有线程)大约需要 2 秒或更多,它将在多线程模式下加速,但如果它更少(比如只需要大约 400 毫秒),它将与正常调用渲染函数的速度相同或慢.这可能表明线程切换非常慢。处理任务越大,它们从多线程中获得的收益就越多。我的任务通常没有那么大,但在单线程模式下不够快。

我还注意到,在 ARM 上构建较慢的多线程和较快的单线程之间的速度差异非常显着(在多线程中几乎是单线程的两倍),而在 x86 上构建的多线程和单线程版本会运行速度与 ARM 构建上的单线程大致相同。所以 x86 构建在多线程上不会变慢,但也不会变快。

是否有其他人有相同的行为或知道减速的原因? Android 上的多线程有什么特殊要求吗?不幸的是,我现在不能真正发布任何代码,但它都是标准的 posix 线程代码,通常在 iOS 和 Mac 上运行良好,并且已经使用了多年。

【问题讨论】:

您当前的 Andriod 和您之前的 iOS 和 Mac 的硬件可能存在差异(核心数)... 我已经尝试了几个 Android 测试设备,它们之间的行为是相同的。有些有 2 个内核,有些有 4 个。iPad 有 2 个。在这种情况下,实际速度不如同一设备上的单线程和多线程版本之间的差异重要。多线程版本应该比单线程版本更快(在 iOS 和 Mac 上),但在 Android 上速度较慢或相同。 多线程并不一定意味着多核。如果您的设备已植根并支持 systrace,您可以确切地看到正在发生的事情。例如,请参阅bigflake.com/systrace。 感谢您的链接,请检查一下。不幸的是,他们没有扎根。我知道多线程并不意味着多核,但我想知道的是多线程为什么/如何在我的多核测试设备上减慢我的应用程序。 在 android 上默认多线程 == 多核(如果硬件当然存在)。我没有这个问题,并且设法在 Android 上使用 CPU 线程来获得预期的加速。尝试从网络上进行基准测试,看看问题出在您的代码中还是在您的 Android 设置上。 【参考方案1】:

Android 供应商积极优化电池寿命,包括保持内核数量(热插拔)和它们各自的(如果可能)频率较低。

在线管理内核数量的一般想法是在一段时间(窗口)内密切关注系统负载。如果负载持续存在并且高于阈值,系统将在线提供必要的额外可用核心。这样的决定总是通过用户级守护进程发生。这种方法通常与台式机有很大不同,因为能够使内核联机/脱机并且它的好处主要取决于 SoC。

管理 cpu 频率也类似,如果负载持续增加 cpu 频率,但 Linux 提供了一种更稳定的机制,称为 cpu-freq,因此桌面和移动设备之间类似。

因此,您创建的 CPU 负载模式很可能不会触发核心启动或频率增加。 (正如您在描述中所描述的那样)

【讨论】:

谢谢 auselen,我会试试看是否有帮助

以上是关于Android NDK - 多线程正在减慢渲染速度的主要内容,如果未能解决你的问题,请参考以下文章

MoviePy:减慢视频的渲染速度

OpenGL - 会使用多个 VBO 减慢渲染速度吗?

Android NDK 在线程内不打印

使用线程拆分任务正在减慢我的工作速度

提高ndk-build编译速度

多线程可以加速内存分配吗?