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

Android NDK - Multithreading is slowing down rendering

本文关键字:速度 NDK 多线程 Android      更新时间:2023-10-16

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

假设我有一个100 x 100的元素数组,我重复地对其进行cpu密集型处理。目前,我将数组分解为四个25 x 100的元素块,并将其传递给四个Posix线程(来自一个停滞的、预先创建的线程池)。这使得iOS和桌面Mac的速度提高了近4倍,但比Android的单线程速度慢。

所以同样的代码可以在iOS或桌面Mac上成功地加速应用程序,但在Android上它通常会使它更慢。

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

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

有没有其他人也有同样的行为,或者知道这种放缓可能来自哪里?Android上的多线程有什么特殊要求吗?不幸的是,我现在不能发布任何代码,但它都是标准的posix线程代码,在iOS和Mac上运行良好,并且已经使用了多年。

Android厂商积极优化电池寿命,包括保持核心数量(热插拔)和他们的个人(如果可能的话)频率低。

管理在线核数的一般思路是在一段时间(窗口)内监视系统负载。如果负载持续并且超过阈值,系统将使必要的额外可用内核在线。这种决策过程总是通过用户级守护进程进行的。这种方法通常与台式机非常不同,因为它能够使核心在线/离线,并且它的好处主要依赖于SoC。

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

所以很有可能你正在创建一个cpu负载模式,它不会触发内核调频或频率增加。