目录
[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)
[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预定义了一些优先级给系统使用。代码详细见如下:
|--------------------------------|-------|------------------|
| 线程优先级 | 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。代码详细见如下所示:
Java优先级最终也要通过系统调用来设置进程的NICE值来调整进程的优先级的。代码如下所示:
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_balance
为1
时生效,值越大,表示负载均衡时查找的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 内存分配器
- scudo
- jemalloc
- Android Extensions(https://android.googlesource.com/platform/bionic/+/HEAD/docs/native_allocator.md)
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
- sensor打分:
- OIS带flash:M3的OIS带有flash,启动速度可以从L1的120ms优化到5ms
- 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
- android官网:https://source.android.google.cn/devices/tech/debug/ftrace?hl=zh-cn
- 查看支持的events:cat /sys/kernel/tracing/available_events
- 设置events: echo "[event]" > /sys/kernel/tracing/set_event
5. Linux perf工具
https://blog.csdn.net/yiyeguzhou100/article/details/102809576
6. eBPF
四、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等等)。