Android性能优化

调度优化

三个方向:

  1. 基础的任务选取
  2. 基于微架构的核选择和调频
  3. 新调度器

与苹果的差距较大,主要在做:

  1. 苹果有一个清晰的行进路线,考虑了足够的影响因素(比如说

游戏优化

1.3.1 基于指令流界面流转(到车机/电视) 相比视频流的好处:

  1. 更清晰
  2. 手机功耗更小(存疑)
  3. 避免了渲染的GPU开销和视频编码开销
  4. 但是增加了网络开销 骨骼动画(顶点压缩)

1.3.2 GPU Turbo

1.3.3 运行时Mesh压缩(点比较小) 现在低端机一般CPU能力还行,但显卡比较弱。 对于GPU能力较弱的手机,渲染大mesh会比较有压力,游戏不主动降mesh顶点数的话,可以在OS侧降。有20%顶点数降低。主要用于卡顿场景。

内存优化

主要是内存分配、内存回收、内存交换三个主题。

内存分配

目标:降低内存管理开销、提升前台应用内存分配性能 手段:动态混合大页、内存反碎片、不公平分配、预加载

动态混合大页

按场景动态地分配4KB、16KB、64KB大页,内存管理效率提升3+倍,流畅性提升。

传统linux内存按4KB为单位分配内存。硬件还支持2MB、1GB等做为内存分配单位。但2M、1GB在普通App的场景下应用不大(主要问题是造成较大的内存碎片,有较大浪费),但是可以应用于相机等需要大块内存的场景。

动态混合大页:所谓混合,就是软件上按64KB管理,硬件上还是4KB为单位的页表。软件一次性分配16个物理页,建16上PTE做为一个大页,做为一个分配单元。所谓动态主是有时分配大页,有时分配小页,根据需要分配。

动态混合大页还可以结合一些其他技术一起使用:

  1. TLB合并,如这个专利,可以将多个物理地址和虚拟地址都连续的页对应的TLB条目合并为一个项,有利于节省TLB条目。

内存回收

目标:提升内存回收的及时性和准确性 手段:冷热数据分享、主动内存回收、内存压缩、异步回收

内存回收是指内存的及时释放,

内存交换

目标:提升系统可用内存,降低TOP应用后台内存占用 手段:内存扩展、内存冻结

基础知识

ARM64 TLB

  1. 分级结构

ARM64 采用了多级 TLB 结构,通常包括一级(L1)TLB 和二级(L2)TLB。L1 TLB 离 CPU 核心更近,访问速度更快,主要用于存放最常使用的地址映射,以提供快速的地址转换。L2 TLB 容量相对较大,作为 L1 TLB 的补充,当 L1 TLB 未命中时,会进一步在 L2 TLB 中查找。这种分级结构有助于在快速访问和存储容量之间取得平衡。

  1. TLB 条目类型

ARM64 的 TLB 条目包含虚拟页号(VPN)、物理页号(PPN)以及一些标志位。标志位用于表示该条目的状态和属性,如是否有效(Valid)、是否可写(Writeable)、是否缓存可命中(Cacheable)等。这些属性对于确保系统的安全性和内存访问的正确性非常重要。例如,如果一个 TLB 条目标志为不可写,CPU 尝试对相应内存区域进行写操作时会触发异常。

  1. TLB 管理与维护

软件管理:操作系统负责 TLB 的管理和维护。当进程切换时,由于新进程的虚拟地址空间不同,之前的 TLB 内容可能不再适用。因此,操作系统需要采取措施来确保 TLB 中的内容与当前进程的地址映射一致。一种常见的方法是在进程切换时清空 TLB(称为 TLB Flush),但这种方法开销较大。为了减少开销,ARM64 架构也支持更细粒度的 TLB 维护操作,如仅刷新特定进程相关的 TLB 条目。 硬件辅助:ARM64 硬件也提供了一些机制来协助 TLB 的管理。例如,当发生页错误(Page Fault,即 TLB 未命中且页表中也未找到有效映射)时,硬件会触发异常,将控制权交给操作系统。操作系统可以在处理异常时更新页表,并相应地更新 TLB,以确保后续的地址转换能够成功。

  1. 缓存一致性:在多核 ARM64 系统中,多个核心可能同时访问内存,并且每个核心都有自己的 TLB。为了确保数据的一致性,需要维护 TLB 之间的一致性。ARM64 采用了缓存一致性协议(如 MESI 协议的变种),当一个核心修改了内存中的数据并更新了其 TLB 时,其他核心的 TLB 中相应的条目需要被无效化或更新,以保证所有核心看到的内存视图是一致的。

  2. 内核中的TLB操作

刷新操作 整体刷新: 在 Linux 内核中,对于 ARM64 架构,flush_tlb_all() 函数用于刷新所有 CPU 上的整个 TLB。该函数通常在系统初始化、内存管理发生重大变化(如页表全局刷新)时使用。

部分刷新: flush_tlb_mm(struct mm_struct *mm):用于刷新指定内存管理结构 mm 对应的整个地址空间的 TLB 条目。通常在进程退出或地址空间被释放时调用。 flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end):刷新指定虚拟内存区域(由 vma 描述,从 start 到 end)对应的 TLB 条目。这在内存区域的映射发生变化时很有用。 无效化操作 tlb_flush_mmu_page(struct vm_fault *vmf):该函数用于使单个页面的 TLB 条目无效,通常在处理页面错误(page fault)时,如果页面的映射需要更新,会调用此函数。 flush_tlb_page(struct vm_area_struct *vma, unsigned long addr):使指定地址对应的单个页面的 TLB 条目无效。