Android Camera性能优化概述

目录

背景

一、性能优化关键点众览

二、性能关键技术

[1. CPU调度](#1. CPU调度)

[1.1 调度单位](#1.1 调度单位)

[1.2 线程状态](#1.2 线程状态)

[1.3 线程优先级](#1.3 线程优先级)

[1.4 CPU调度策略](#1.4 CPU调度策略)

[1.4.1 调度器](#1.4.1 调度器)

[1.4.2 CPUFreq Governor](#1.4.2 CPUFreq Governor)

[1.4.3 CGroup](#1.4.3 CGroup)

[1.5 PerfLock](#1.5 PerfLock)

[1.6 进程冻结](#1.6 进程冻结)

[1.7 LMKD](#1.7 LMKD)

[1.7.1 水线](#1.7.1 水线)

[1.7.2 ADJ](#1.7.2 ADJ)

[1.8 温控](#1.8 温控)

[1.8.1 温控配置和策略](#1.8.1 温控配置和策略)

[2. IO调度](#2. IO调度)

[3. 内存分配](#3. 内存分配)

[3.1 内存分配器](#3.1 内存分配器)

[3.2 内存压缩和回收](#3.2 内存压缩和回收)

[3.3 Camera内存](#3.3 Camera内存)

[4. 锁机制](#4. 锁机制)

[5. IPC](#5. IPC)

[6. Graphics Framework](#6. Graphics Framework)

[7. HW Performance](#7. HW Performance)

三、性能分析工具

[1. Perfetto/Systrace/Atrace](#1. Perfetto/Systrace/Atrace)

[2. Simpleperf & 火焰图](#2. Simpleperf & 火焰图)

[3. Android Profiler](#3. Android Profiler)

[4. ftrace](#4. ftrace)

[5. Linux perf工具](#5. Linux perf工具)

[6. eBPF](#6. eBPF)

四、Camera场景性能分析

1.启动

[1.1 冷启动](#1.1 冷启动)

[1.1.1 关键路径](#1.1.1 关键路径)

[1.1.2 流程分析](#1.1.2 流程分析)

[1.1.3 关键点](#1.1.3 关键点)

[1.2 热启动](#1.2 热启动)

[1.2 预览卡顿](#1.2 预览卡顿)

[2. 模式切换](#2. 模式切换)

[3. Lens切换](#3. Lens切换)

[4. 拍照](#4. 拍照)

[5. 录像](#5. 录像)

五、优化点

[1. 异步化](#1. 异步化)

[2. 提前和延后](#2. 提前和延后)

[3. IO](#3. IO)

[4. 调度优化](#4. 调度优化)

[5. 业务逻辑优化](#5. 业务逻辑优化)

小结


背景

做camera性能优化方面的工作有几年了,想写一篇文章简单介绍一下其中涉及到的具体技术,这篇文章会大概介绍一下涉及到的技术。

一、性能优化关键点众览

**性能优化分析方向:**给了多少资源和做了多少事。

  • 给多少资源主要是硬件方面资源,比如CPU频率、GPU频率、NPU频率、外设IO总线的clock、memory大小等,需要重点关注分配给当前task的资源,尤其是CPU时间片。在平衡功耗、内存和稳定性后应当最大化供给;
  • 做多少事主要是从软件角度触发,聚焦于业务逻辑的优化,以及整个系统的优化,不执行冗余代码,尽可能不阻塞关键路径和抢占其资源。
  • 达成目标: 快且流畅,减少迟滞、波动(时快时慢)和不连贯(丢帧)给用户带来的心理落差。总结三个字就是:快、稳、省。
  • **优化建议:**有全局观,抓主要矛盾,综合取舍。

二、性能关键技术

1. CPU调度

1.1 调度单位

线程是Linux的最小调度单位,而资源是以进程为单位进行分配和管理,包括程序(program text)、数据(data )、文件(open file)等,这些资源由同一进程下的线程共享。

1.2 线程状态

分析性能问题时,主要关注下面几种状态:

  • Running(R): 线程在正常执行代码逻辑
  • Runnable(R): 可执行状态,等待调度,如果长时间调度不到,说明CPU繁忙
  • Sleeping(S): 休眠,一般是在等待事件驱动
  • Uninterruptible Sleep(D): 不可中断的休眠,需要看Args的描述来确定当时的状态
  • Uninterruptible Sleep - Block I/O(D): IO阻塞

1.3 线程优先级

Linux线程优先级

Linux线程优先级的范围是 0 ~ 139,值越小,优先级越高。userspace线程优先级的范围是 100 ~ 139,默认创建的线程优先级是120,对应的nice值是0,nice值的范围是 -20 ~ 19,对应的优先级是 100 ~ 139。只有内核线程才支持低于100的优先级,优先级低于100的线程称为RT级线程。

前面值的定义可以从如下链接 https://cs.android.com/android/kernel/superproject/+/common-android-mainline:common/include/linux/sched/prio.h?q=linux%2Fsched%2Fprio.h 获取。

Android的Process类封装了线程优先级设置接口,范围是 -20 ~ 19,跟Linux的nice值一致。Android预定义了一些优先级给系统使用。代码详细见如下:

https://cs.android.com/android/platform/superproject/+/android14-qpr3-release:frameworks/base/core/java/android/os/Process.java?q=java%2Fandroid%2Fos%2FProcess.java

|--------------------------------|-------|------------------|
| 线程优先级 | nice值 | 解释 |
| THREAD_PRIORITY_LOWEST | 19 | 最低优先级 |
| THREAD_PRIORITY_BACKGROUND | 10 | 后台 |
| THREAD_PRIORITY_LESS_FAVORABLE | 1 | 比默认略低 |
| THREAD_PRIORITY_DEFAULT | 0 | 默认 |
| THREAD_PRIORITY_MORE_FAVORABLE | -1 | 比默认略高 |
| THREAD_PRIORITY_FOREGROUND | -2 | 前台 |
| THREAD_PRIORITY_DISPLAY | -4 | 显示相关 |
| THREAD_PRIORITY_URGENT_DISPLAY | -8 | 显示(更为重要),input事件 |
| THREAD_PRIORITY_AUDIO | -16 | 音频相关 |
| THREAD_PRIORITY_URGENT_AUDIO | -19 | 音频(更为重要) |

Java线程优先级

Java标准接口是通过Thread类设置优先级,范围为1 ~ 10。代码详细见如下所示:

https://cs.android.com/android/platform/superproject/main/+/main:libcore/openjdk_java_files.bp;l=250?q=main%2Fjava%2Fjava%2Flang%2FThread.java

Java优先级最终也要通过系统调用来设置进程的NICE值来调整进程的优先级的。代码如下所示:

https://cs.android.com/android/platform/superproject/+/android14-qpr3-release:art/runtime/thread.cc?q=art%2Fruntime%2Fthread.cc

java 复制代码
static const int kNiceValues[art::palette::kNumManagedThreadPriorities] = {
        ANDROID_PRIORITY_LOWEST,  // 1 (MIN_PRIORITY)
        ANDROID_PRIORITY_BACKGROUND + 6,
        ANDROID_PRIORITY_BACKGROUND + 3,
        ANDROID_PRIORITY_BACKGROUND,
        ANDROID_PRIORITY_NORMAL,  // 5 (NORM_PRIORITY)
        ANDROID_PRIORITY_NORMAL - 2,
        ANDROID_PRIORITY_NORMAL - 4,
        ANDROID_PRIORITY_URGENT_DISPLAY + 3,
        ANDROID_PRIORITY_URGENT_DISPLAY + 2,
        ANDROID_PRIORITY_URGENT_DISPLAY  // 10 (MAX_PRIORITY)
};

palette_status_t PaletteSchedSetPriority(int32_t tid, int32_t managed_priority) {
    if (managed_priority < art::palette::kMinManagedThreadPriority ||
        managed_priority > art::palette::kMaxManagedThreadPriority) {
        return PALETTE_STATUS_INVALID_ARGUMENT;
    }
    int new_nice = kNiceValues[managed_priority - art::palette::kMinManagedThreadPriority];
    int curr_nice = getpriority(PRIO_PROCESS, tid);

    if (curr_nice == new_nice) {
        return PALETTE_STATUS_OK;
    }

    if (new_nice >= ANDROID_PRIORITY_BACKGROUND) {
        SetTaskProfiles(tid, {"SCHED_SP_BACKGROUND"}, true);
    } else if (curr_nice >= ANDROID_PRIORITY_BACKGROUND) {
        SchedPolicy policy;
        // Change to the sched policy group of the process.
        if (get_sched_policy(getpid(), &policy) != 0) {
            policy = SP_FOREGROUND;
        }
        SetTaskProfiles(tid, {get_sched_policy_profile_name(policy)}, true);
    }

    if (setpriority(PRIO_PROCESS, tid, new_nice) != 0) {
        return PALETTE_STATUS_CHECK_ERRNO;
    }
    return PALETTE_STATUS_OK;
}
  • MAX_PRIORITY相当于android.os.Process.THREAD_PRIORITY_URGENT_DISPLAY,值为10;
  • MIN_PRIORITY相当于android.os.Process.THREAD_PRIORITY_LOWEST,值为0;
  • NORM_PRIORITY相当于android.os.Process.THREAD_PRIORITY_DEFAULT,值为5。

1.4 CPU调度策略

1.4.1 调度器

高通从Kernel 4.9之后使用EAS (Energy Aware Scheduling)作为CPU调度器。EAS针对异构 CPU 架构(Arm big.LITTLE)设计,其调度算法基于 CFS 任务唤醒平衡代码,当时引入能量模型( EM)在调度任务时选择节能目标CPU,在保证性能的前提下尽可能地降低功耗。

1.4.2 CPUFreq Governor

跟EAS配合动态调整CPU频点。对性能影响较大,需要了解governor提供的参数配置进行tune来达到较佳效果。

  • Walt

  • Schedutil

1.4.3 CGroup

CGroups是control groups的缩写,是Linux内核提供的一种可以限制、记录、隔离进程组(process groups)所使用的物理资源(cpu,memory,IO等等)的机制。CGroups提供了以下功能:

  • 限制进程组可以使用的资源数量(Resource limiting )。比如:memory子系统可以为进程组设定一个memory使用上限,一旦进程组使用的内存达到限额再申请内存,就会出发OOM(out of memory)。
  • 进程组的优先级控制(Prioritization )。比如:可以使用cpu子系统为某个进程组分配特定cpu share。
  • 记录进程组使用的资源数量(Accounting )。比如:可以使用cpuacct子系统记录某个进程组使用的cpu时间
  • 进程组隔离(Isolation)。比如:使用ns子系统可以使不同的进程组使用不同的namespace,以达到隔离的目的,不同的进程组有各自的进程、网络、文件系统挂载空间。
  • 进程组控制(Control)。比如:使用freezer子系统可以将进程组挂起和恢复。

根据谷歌文档(https://source.android.com/devices/tech/perf/cgroups), Android 9 及更低版本,只能通过init.rc初始化脚本创建及挂载cgroup,而Android 10 及更高版在early-init阶段挂载,在cgroups.json文件中配置cgroup组及挂载路径属性等。

cgroups其挂载也可以用下面命令查看。

java 复制代码
thor:/ # mount -t cgroup
none on /dev/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
none on /dev/cpuctl type cgroup (rw,nosuid,nodev,noexec,relatime,cpu)
none on /dev/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset,noprefix,release_agent=/sbin/cpuset_release_agent)
none on /dev/memcg type cgroup (rw,nosuid,nodev,noexec,relatime,memory)

查看进程的cgroup配置,如camera provider:

java 复制代码
thor:/ # cat /proc/$(pidof vendor.qti.camera.provider@2.7-service_64)/cgroup
4:memory:/camera/provider
3:cpuset:/camera-daemon
2:cpu:/foreground
1:blkio:/
0::/uid_1047/pid_1197
  • cpuset

|--------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 文件节点 | 作用 | |
| tasks | 列举绑定到某个 cgroup的所有线程程ID,将线程ID写入此文件会将线程移至该cgroup。 | cgroup通用 |
| cgroup.procs | cgroup中的进程ID的列表,将进程ID写入此文件会将进程移至该cgroup。 | cgroup通用 |
| notify_on_release | flag 文件: :填 0 或 1,表示是否在 cgroup 中最后一个 task 退出时通知运行release agent,默认情况下是 0,表示不运行 | cgroup通用 |
| release_agent | 指定 release agent 执行脚本的文件路径(此文件仅在顶级cgroup中存在),在这个脚本通常用于自动化umount无用的 cgroup | cgroup通用 |
| cgroup.clone_children | 该标志仅影响cpuset控制器。 如果在cgroup中启用了 clone_children 标志(1),则新的cpuset cgroup将在初始化期间从父级复制其配置。 | cpuset特有 |
| cpuset.cpus | 限制一组进程所能使用的cpu, 供用户进行设置 | |
| cpuset.cpu_exclusive | flag:设置为1时,说明独占指定cpus,默认为0 独占cpu的意思是,如果某个cpuset是独占的,那么该cpuset中的cpu是不能被该cpuset的兄弟cpuset共享的,当然该cpuset中的cpu是能够和该cpuset的祖先cpuset和子孙cpuset共享的。 注意:设置exclusive时,需要其父节点也为exclusive。否则会设置失败。所以,最终还是说明cpuset的独占,就是从根节点开始,就已经独占了。 | |
| cpuset.effective_cpus | 显示实际进程可以使用的cpu | |
| sched_load_balance | flag:默认为值1,表示进程会在该cpuset中允许的cpu上进行负载均衡 | |
| sched_relax_domain_level | 可设置的值为-1到一个较小的整数值,只有sched_load_balance1时生效,值越大,表示负载均衡时查找的cpu范围越大 | -1 : no request. use system default or follow request of others. 0 : no search. 1 : search siblings (hyperthreads in a core). 2 : search cores in a package. 3 : search cpus in a node [= system wide on non-NUMA system] 4 : search nodes in a chunk of node [on NUMA system] 5 : search system wide [on NUMA system] |
| mems相关节点 | android只有一个内存节点,用不到 | |

  • cpuctl

|------------------------------|------------------------------------------------|---|
| 文件节点 | 作用 | |
| tasks | 列举绑定到某个 cgroup的所有线程程ID,将线程ID写入此文件会将线程移至该cgroup | |
| cgroup.clone_children | | |
| cgroup.procs | | |
| cpu.shares | 限制cgroup的cpu相对使用比例,值越大拿到的CPU资源越多 | |
| cpu.uclamp.latency_sensitive | | |
| cpu.uclamp.max | | |
| cpu.uclamp.min | | |
| notify_on_release | | |

  • 任务配置文件(Task profiles file)

Android 10之后使用task_profiles.json(https://source.n.xiaomi.com/opengrok-s/xref/pangu_8450-s-combine/system/core/libprocessgroup/profiles/task_profiles.json)作为任务配置文件,提供了一种抽象概念将必需的功能与该功能的实现详情分离。Android 框架使用 SetTaskProfiles 和 SetProcessProfiles API,按照 task_profiles.json 文件中的描述将任务配置文件应用于进程或线程(这些 API 是 Android 11 及更高版本所独有的)。为了实现向后兼容,旧版函数 set_cpuset_policy、set_sched_policy 和 get_sched_policy 提供相同的 API 和功能,但其实现已修改为使用任务配置文件。对于新的用例,AOSP 建议使用新的任务配置文件 API,而不是旧版 set_sched_policy 函数。

  • 组优先级

|-----------------------------------------------------------------------------|-----------------------------------------|-------------------------------------|
| 组优先级Process.java | 优先级策略 SchedPolicy | 对应cpuset group级别 sched_policy.cpp |
| THREAD_GROUP_BACKGROUND 0 | SP_BACKGROUND | /dev/cpuset/background/tasks |
| THREAD_GROUP_FOREGROUND 1 THREAD_GROUP_AUDIO_APP 3 THREAD_GROUP_AUDIO_SYS 4 | SP_FOREGROUND SP_AUDIO_APP SP_AUDIO_SYS | /dev/cpuset/foreground/tasks |
| THREAD_GROUP_TOP_APP 5 | SP_TOP_APP | /dev/cpuset/top-app/tasks |
| THREAD_GROUP_SYSTEM 2 | SP_SYSTEM | /dev/cpuset/system-background/tasks |
| THREAD_GROUP_RESTRICTED 7 | SP_RESTRICTED | /dev/cpuset/restricted/tasks |
| THREAD_GROUP_RT_APP 6 | SP_RT_APP | N/A |

AMS在调度过程根据优先级进行分组,同时,进程也可以使用api设置资源使用优先级以及分组。如果有权限,还可以把task id写入cpuset中。常见的是 APP 使用AsyncTask类,在doInBackground中执行优先级较低的代码,其实就是把该task分到BACKGROUND的组

可以利用cgroup机制,改善了provider进程出现长时间runnable的问题。

总的来时,CPU调度的优化最终会影响task的vruntime(虚拟运行时间),vruntime记录了一个task到当前时刻为止执行的总时间(需要以task总数n进行归一化,并且根据task的优先级进行加权)。vruntime越大,说明该进程运行的越久,所以被调度的可能性就越小。

1.5 PerfLock

//后续有文章进行详细介绍

1.6 进程冻结

//后续有文章进行详细介绍

1.7 LMKD

1.7.1 水线
  • 水线配置

可以使用下面命令查看内存水线设置。

java 复制代码
thor:/ # getprop sys.lmk.minfree_levels

18432:0,23040:100,27648:200,32256:250,55296:900,80640:950
  • 双水线

相机切换到前台时会更新水线设置,适当降低内存回收力度。

1.7.2 ADJ

ADJ值范围为-1000 - 1000,通过cat /proc/[pid]/oom_score_adj查看。系统在剩余内存低于水线阈值时,为了维护正在运行的进程,杀掉优先级比较低(adj值比较高)的其他进程。

|------------------------|-------|----------------------------------|
| ADJ级别 | 取值 | 含义 |
| NATIVE_ADJ | -1000 | native进程 |
| SYSTEM_ADJ | -900 | 仅指system_server进程 |
| PERSISTENT_PROC_ADJ | -800 | 系统persistent进程 |
| PERSISTENT_SERVICE_ADJ | -700 | 关联着系统或persistent进程 |
| FOREGROUND_APP_ADJ | 0 | 前台进程 |
| VISIBLE_APP_ADJ | 100 | 可见进程 |
| PERCEPTIBLE_APP_ADJ | 200 | 可感知进程,比如后台音乐播放 |
| BACKUP_APP_ADJ | 300 | 备份进程 |
| HEAVY_WEIGHT_APP_ADJ | 400 | 重量级进程 |
| SERVICE_ADJ | 500 | 服务进程(A list中的service) |
| HOME_APP_ADJ | 600 | Home进程 |
| PREVIOUS_APP_ADJ | 700 | 上一个进程 |
| SERVICE_B_ADJ | 800 | B List中的Service |
| CACHED_APP_MIN_ADJ | 900 | 不可见进程的adj最小值 |
| CACHED_APP_MAX_ADJ | 906 | 不可见进程或不含任何活动的应用组件的empty进程的adj最大值 |

1.8 温控

1.8.1 温控配置和策略

1.8.2 thermald

//后续有时间详细介绍

2. IO调度

IO调度策略、IO block和IO优化(prefetch等),这块内容比较多,后续有空会详细介绍。

3. 内存分配

3.1 内存分配器

mallopt(M_DECAY_TIME, 1)和mallopt(M_PURGE, 0),其中mallopt(M_PURGE, 0)耗时长问题。

3.2 内存压缩和回收

  • ZRAM
  • 内存回收机制
  • 内存碎片整理

https://blog.csdn.net/buhui912/article/details/115895277

3.3 Camera内存

  • imagebuffer
  • metadata pool
  • ion/no-ion
  • HALBufferManager

https://source.android.com/devices/camera/buffer-management-api: Android对HALBufferManager的定义

Camera HAL3 Buffer Management详解

Camera Service buffer与HAL交互

CameraService Buffer如何与HAL交互

高通StreamBufferManager学习

4. 锁机制

  • Java锁
  • pthread mutex、condition
  • futex
  • FileLock

5. IPC

  • binder/aidl/hidl:线程优先级继承、oneway
  • broadcast的性能问题
  • local socket

6. Graphics Framework

https://blog.csdn.net/u012365926/article/details/114921456

  • SurfaceFlinger: composer、vsync
  • BufferQueue: producer、consumer、fence、Gralloc
  • GLRender

界定方法

7. HW Performance

  • GPU/DDR/DSP/HTP/ISP/NCS sensor/videoEncoder(OMX)/BUS(CCI&MIPI):clock、loading、usage
  • sensor node (ois,actuator、otp)、IPE、IFE
  1. sensor打分:
  2. OIS带flash:M3的OIS带有flash,启动速度可以从L1的120ms优化到5ms
  3. I2C总线合理挂载slave:避免同时使用的硬件发生抢占,提高camera工作是多给CCI总线能做到并行传输,以此提高性能

三、性能分析工具

1. Perfetto/Systrace/Atrace

https://perfetto.dev/docs/#/?id=perfetto-performance-instrumentation-and-tracing

https://perfetto.dev/docs/data-sources/memory-counters

https://perfetto.dev/docs/quickstart/android-tracing

2. Simpleperf & 火焰图

  • simpleperf指令:record和report等;
  • android源码丰富的解析脚本.
  • FlameGraph和红蓝火焰图

3. Android Profiler

https://developer.android.com/studio/profile/android-profiler

  • 集成在AndroidStudio中;
  • 需要有APP的源码;
  • 可以抓java和native调用堆栈。

4. ftrace

5. Linux perf工具

https://blog.csdn.net/yiyeguzhou100/article/details/102809576

6. eBPF

Android中的eBPF程序简介-CSDN博客

四、Camera场景性能分析

1.启动

1.1 冷启动

1.1.1 关键路径

//关键流程分析

1.1.2 流程分析

1.1.2.1 APP进程保活

  • 保活机制FastRestart
  • 相机被kill掉后3秒多能被保活机制拉起
java 复制代码
02-04 20:17:03.192  4312  4312 D RecentsContainer: removeTask: [id=105 stackId=0 windowingMode=1 user=0 lastActiveTime=318591997, component=ComponentInfo{com.a
ndroid.camera/com.android.camera.Camera}] 相机
02-04 20:17:03.214  2226  5341 D WindowProcessUtils: remove task: Task{9fdb79 #105 type=standard A=10089:com.android.camera U=0 visible=false mode=fullscreen t
ranslucent=true sz=1}
02-04 20:17:03.215  2226  5341 I SplashScreenServiceDelegate: None for com.android.camera
02-04 20:17:03.241  2226  5341 I ProcessManager: OneKeyClean: kill com.android.camera Adj=900 State=16
02-04 20:17:03.241  2226  5341 I ActivityManager: Killing 23899:com.android.camera/u0a89 (adj 900): OneKeyClean
02-04 20:17:03.242  2226  5341 D PerfImpl: perfProcessKillBoost: com.android.camera, 23899, 0
02-04 20:17:03.533  2226  2260 W UsageStatsService: Unexpected activity event reported! (com.android.camera/com.android.camera.Camera event : 23 instanceId : 2
31437437)
02-04 20:17:05.554  2226  2298 D Boost   : hostingType=FastRestart, hostingName=com.android.camera, callerPackage=android, isSystem=true, isBoostNeeded=false.
02-04 20:17:05.554  2226  2298 I ActivityManager: Start proc 27596:com.android.camera/u0a89 for FastRestart com.android.camera caller=android
02-04 20:17:05.596  5231 11184 W MQSService: CallerName:com.android.camera,calling Uid:10089
02-04 20:17:05.596  5231 11184 D MQSService: registerApplicationScoutThread pid = 27596, packageName = com.android.camera
02-04 20:17:05.709 27596 27596 V GraphicsEnvironment: ANGLE Developer option for 'com.android.camera' set to: 'default'
02-04 20:17:05.712 27596 27596 I ForceDarkHelperStubImpl: initialize for com.android.camera , ForceDarkOrigin
02-04 20:17:05.800 27596 27596 D CAM_BoostFrameworkImpl: stopBoost: com.android.camera.CameraAppImpl.attachBaseContext:42
02-04 20:17:05.838 27596 27596 D CAM_BoostFrameworkImpl: stopBoost: com.android.camera.CameraAppImpl.onCreate:12
02-04 20:17:05.845 27596 27596 D MiCameraAlgo: init: application file path to algorithm lib: /data/user/0/com.android.camera/files
02-04 20:17:05.860 27596 27596 D CAM_AlgoConnector: onServiceConnected: ComponentInfo{com.android.camera/com.android.camera.LocalParallelService}, binder = com
  • Application启动

大致流程:ZygoteInit->ActivityThreadMain->bindApplication->serviceCreate->serviceBind

1.1.2.2 启动Trace分析

  • 关键trace点
    • iq
    • startActivityInner
    • activityStart/activityResume ...

HAL3: RequestTrace/HAL3ProcessCapture/ProcessRequest [request id]/ProcessRequestIdDone/HAL3ProcessCaptureResult ...

1.1.3 关键点
  • CPU频率设置
  • 关键线程runnable和sleep情况

1)running使用trace跟火焰图分析

2)sleep开hal的sync

3)runnable看trace中CPU的抢占

  • APP关键操作的衔接
  • HAL pipeline

1.2 热启动

1.2.1 关键路径

1.2.2 流程分析

1.2.3 关键点

1.2 预览卡顿

生产者和消费者

2. 模式切换

3. Lens切换

4. 拍照

5. 录像

五、优化点

1. 异步化

2. 提前和延后

避免集中化

3. IO

  • pin
  • 预加载

4. 调度优化

google相关内容

5. 业务逻辑优化

  • 线程优先级
  • 绑核
  • 调度参数调优
  • vruntime补偿
  • EarlyPCR
  • 提前active pipeline
  • offline feature延后create
  • 等等

小结

以上简单总结了一下camera性能优化基础的关键点内容,最重要的其实就是2大类知识。

1.熟练掌握 Linux/Android系统 进程调度,内存管理,文件系统,网络通信等知识点

2.熟练掌握camera系统业务知识,要非常熟悉camera业务关键流程(open/configure/request/result/close等等)。

相关推荐
シ風箏1 小时前
Neo4j【环境部署 02】图形数据库Neo4j在Linux系统ARM架构下的安装使用
linux·数据库·arm·neo4j
理想不理想v2 小时前
前端项目性能优化(详细)
前端·性能优化
Cachel wood3 小时前
Vue.js前端框架教程8:Vue消息提示ElMessage和ElMessageBox
linux·前端·javascript·vue.js·前端框架·ecmascript
小屁不止是运维6 小时前
麒麟操作系统服务架构保姆级教程(二)ssh远程连接
linux·运维·服务器·学习·架构·ssh
花追雨7 小时前
Android -- 双屏异显之方法一
android·双屏异显
小趴菜82277 小时前
安卓 自定义矢量图片控件 - 支持属性修改矢量图路径颜色
android
氤氲息7 小时前
Android v4和v7冲突
android
KdanMin7 小时前
高通Android 12 Launcher应用名称太长显示完整
android
chenjk47 小时前
Android不可擦除分区写文件恢复出厂设置,无法读写问题
android
袁震7 小时前
Android-Glide缓存机制
android·缓存·移动开发·glide