我有一个带有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上运行良好,并且已经使用多年。
答案 0 :(得分:1)
Android供应商积极优化电池续航时间,包括保持核心数(热插拔)及其个人(如果可能)频率较低。
在线管理核心数量的一般想法是关注一段时间(窗口)的系统负载。如果加载持续且超过阈值,系统将在线提供必要的其他可用内核。这种决定采取afaik总是通过用户级守护进程发生。这种方法通常与台式机非常不同,因为它能够在线/离线运行核心,并且它的好处主要取决于SoC。
管理cpu频率也是类似的,如果加载持续存在cpu freq增加但是Linux提供了一个更加稳定的机制,称为cpu-freq,因为它在桌面和移动设备之间是相似的。
因此,您很可能正在创建一个不会触发核心启动或频率增加的CPU加载模式。 (正如您在描述中所描述的那样)