Qualcomm Linux(QCS6490/QCS5430) 性能指南(二)

特性

系统性能受多个组件的影响,包括 CPU 调度器、CPU 频率调节器、性能抽象层 (PerfHAL)、动态电压频率调节 (DVFS) 和内存管理。
Linux 内核提供了标准功能,如 CPU 调度器、CPU 频率调节器、DVFS 和内存管理。本指南提供了每个功能的概述及相关参考链接。此外,PerfHAL 是 Qualcomm 添加的一个功能,用于增强性能。

CPU 调度器

CPU 调度器负责管理在 Linux 系统上运行的进程之间的 CPU 时间分配。
CPU 架构使用 Arm big.LITTLE 技术,包含以下核心:

  • 4 个大核心 – 1 个 Prime 核心和 3 个 Gold 核心
  • 4 个小核心(也称为 Silver 核心)

CPU 调度器使用最早可用虚拟截止时间优先 (EEVDF) 调度器,这是 Linux 内核提供的功能。EEVDF CPU 调度器使用每实体负载追踪 (PELT) 来监控任务负载。

  • 有关 EEVDF 调度器的更多信息,请参见 An EEVDF CPU scheduler for Linux。
  • 有关 PELT 的更多信息,请参见 Per-entity load tracking。

Utilization clamping (UCLAMP 或者 util clamp) 是一种调度器功能,使任务的性能需求管理成为可能。更多信息请参见 https://docs.kernel.org/scheduler/sched-util-clamp.html。
有关相关信息,请参见 Customize CPU scheduler。

CPU 频率调节器

CPU 频率调节器负责根据系统负载调整 CPU 频率,该负载由正在执行的任务确定。CPU 调度器提供此过程中所需的输入。
Qualcomm Linux 使用 schedutil 调节器,这是 Linux 内核提供的功能。
此调节器在系统负载高时增加频率,在负载低时降低频率,确保功耗与性能之间的最佳平衡。
有关 CPU 频率调节器的更多信息,请参见 https://www.kernel.org/doc/Documentation/cpu-freq/governors.txt 和 https://www.kernel.org/doc/html/v5.0/admin-guide/pm/cpufreq.html。
有关 CPU 频率调节器配置和定制的更多信息,请参见 Configure CPU and Customize CPU frequency governor。

DVFS 调节器

DVFS 调节器根据系统工作负载控制 CPU 缓存 (L3)、最后一级缓存控制器 (LLCC) 和 DDR 的频率。
这些调节器在工作负载高时增加频率,在工作负载低时降低频率,确保功耗与性能之间的最佳平衡。
Qualcomm Linux 支持两种类型的 L3 缓存、LLCC 和 DDR DVFS 调节器。

静态映射 DVFS 调节器

此调节器将 CPU L3 缓存和 DDR 的频率与当前操作的 CPU 频率对齐,以平衡功耗和性能需求。
例如,如果 CPU 频率处于最大值,则 L3 缓存和 DDR 频率也必须处于最大水平,以实现最佳性能和功耗效率。
QCS6490 和 QCS5430 的静态映射可以在源代码 kernel/arch/arm64/boot/dts/qcom/sc7280.dtsi 中找到。
有关定制选项,请参见 Customize static map DVFS governor。

BWMON 调节器

带宽监控 (BWMON) 调节器根据从 CPU 到 LLCC 再到 DDR 的测量流量动态调整 LLCC 和 DDR 的频率。
BWMON 硬件模块测量此流量。它在指定的采样窗口内监控内存与其他子系统之间的数据吞吐量,并使用这些信息来调整 LLCC 和 DDR 频率以满足所需的带宽。
BWMON 调节器驱动程序可以在源代码 drivers/soc/qcom/icc-bwmon.c 中找到。
有关 BWMON 的更多信息,请参见 [PATCH v3 0/4] soc/arm64: qcom: Add initial version of bwmon](https://patchwork.kernel.org/project/linux-arm-msm/patch/20190412052812.8902-1-rnayak@codeaurora.org/)。
有关定制选项,请参见 Customize BWMON governor。

PerfHAL

PerfHAL 是 Qualcomm 的专有服务,通过使 perflock API 可访问来提供额外功能。当需要短期性能增强或节能时,它非常有用。
Perflock 帮助修改系统行为以管理间歇性工作负载。例如,如果某段代码需要在一段时间内以更高的 CPU 频率运行,可以在代码中使用 perflock 来提升 CPU 频率。
PerfHAL 高效处理来自多个客户端的并发 perflock 请求。当多个请求针对同一资源时,PerfHAL 会聚合它们以达到设备所需的最佳性能水平。
当客户端的 perflock 不再活动时,PerfHAL 会释放与该客户端关联的所有 perflock。

Perflock API

Perflock API 旨在允许应用程序调整系统参数以满足特定用例,帮助它们实现性能和功耗目标。
用户空间应用程序使用 perf_lock_acq() 和 perf_lock_rel() API 来请求系统可调参数的特定值,持续一段时间或无限期。

获取 perflock

perf_lock_acq() 函数用于获取 perflock 以及必要的优化列表。
此函数的语法如下:int perf_lock_acq(int handle, int duration, int list[], int numArgs)。
参数 duration 可以设置为特定时间或无限期(0)。
对于定时或特定时长,当时长到期后,perflock 会自动释放。
要手动释放设置为无限期的 perflock,可以使用 perf_lock_rel() 函数。
在这里插入图片描述

释放 Perflock

perf_lock_rel() 函数用于释放持有的 perflock。
如果 perflock 有确定的持续时间,则不需要调用 perf_lock_rel(),因为 perflock 会在时长到期时自动释放。要使用 perf_lock_rel() API,可以运行以下命令:

int perf_lock_rel(int handle)

在这里插入图片描述

资源操作码

Perflock 使用操作码及其对应值的组合来对 perflock 资源执行特定操作。
一个 perflock 可以接受多个操作码,这些操作码在源代码 sources\vendor\qcom\proprietary\perf-core\extnIntf\PerflocksResources.h 中定义。
下表列出了支持的操作码:
在这里插入图片描述
以下是一些资源操作码的示例:

  • 0x44004100, 1958400:这一对操作码和值表示 Silver 集群的最低频率必须设置为 1958400 KHz。
  • 0x44004100, 1958400, 0x44008100, 2100000:这一组操作码和值表示 Silver
    集群的最低频率必须设置为 1958400 KHz,最高频率必须设置为 2100000 KHz。

有关如何使用和调试 perflock 的更多信息,请参见 Customize perflock。

内存

RAM 用于软件进行的所有内存分配。有效管理 RAM 对于满足性能要求和确保应用程序的顺利运行至关重要。
在这里插入图片描述
某些 RAM 区域是独立于 Linux 系统管理的。例如,调制解调器、视频和音频等固件在这些特定的 RAM 分区中运行。Linux 内核管理所有其他 RAM 分区。
Linux 内核具有自己的内存管理子系统,包括以下组件:

  • 虚拟内存和按需分页的实现
  • 为内核内部结构和用户空间程序分配内存
  • 将文件映射到进程的地址空间
  • 其他内存管理操作

RAM 内存分区

这里是各种类型的内存分配。

Non-Linux:
  • 内存以 carveouts 的形式由 Linux 之外的各种子系统保留。
  • 这些 carveouts 在相应的 DTSI 文件中指定。
Linux(system RAM)
内核静态内存:

Vmlinux + 内核分页结构:

  • 这些内存在启动时由内核保留供其自身使用。
  • vmlinux 是用于存储 vmlinux 映像的内存。
  • vmlinux 映像的大小和细分可以从启动时的 dmesg 日志中获取:
    Memory: 3061872K/4134912K available (28800K kernel code, 2090K rwdata, 10688K rodata, 3072K init, 969K bss, 679824K reserved, 393216K cma-reserved)
    内核代码 + 读写数据 (rwdata) + 只读数据 (rodata) + 初始化数据 (init) + BSS 表示 vmlinux
    内核映像的大小(28800K + 2090K + 10688K + 3072K + 969K)。
  • 内核分页结构是内核用于维护每个 RAM 页面结构的内存。其计算方式为每 GB RAM 大小需要 16 MB 的内存。
内核动态内存:

Slab:
Slab 机制由内核使用,用于更快、更高效地处理频繁使用的数据结构的内存。
要检查 Slab 的内存使用情况,请运行以下命令:

cat /proc/meminfo | grep -i slab

要了解各个 Slab 的详细信息及其使用情况,请在内核配置中启用 CONFIG_SLUB_DEBUG,然后运行以下命令:

cat /proc/slabinfo

内核栈
内核栈存储每个进程的调用栈。
要检查内核栈的内存使用情况,请运行以下命令:

cat /proc/meminfo | grep -i kernelstack

页表 (PageTables)
内核使用内存来存储将虚拟地址映射到物理地址的页表。
要检查页表的内存使用情况,请运行以下命令:

cat /proc/meminfo | grep -i PageTables

模块 (Modules)
表示以内核模块形式动态加载到内核中的内核实体。
要显示加载的内核模块及其内存使用情况,请运行以下命令:

cat /proc/modules

Vmalloc
用于分配虚拟连续的内存。
要检查 Vmalloc 内存的详细信息,请运行以下命令:

cat /proc/vmallocinfo

缓存 (Cached)(内核 + 用户空间)
驻留在 RAM 中的文件支持的内存量。
要检查缓存内存的使用情况,请运行以下命令:

cat /proc/meminfo | grep -i cached

缓冲区 (Buffers)
缓冲区是固定大小的,包含从磁盘读取或写入磁盘的信息块。
要检查缓冲区的内存使用情况,请运行以下命令:

cat /proc/meminfo | grep -i buffers

共享内存 (Shmem)
共享内存是映射到两个或多个进程地址空间的公共内存块。
要检查共享内存的使用情况,请运行以下命令:

cat /proc/meminfo | grep -i shmem
用户空间内存:

ZUSED (ZRAM)
ZUSED 是由 ZRAM 压缩后的匿名内存。

CMA
CMA(连续内存分配)通常被映射到其他 IP(如视频和显示),但在运行时分配。
使用更多的 CMA 保留会减少系统可以使用的空闲内存。CMA 保留的空闲内存只能用于可移动分配,如用户空间进程分配。但是,它不能用于内核分配。

ANON
ANON 是用户空间应用程序使用 malloc() 或 new() 函数调用分配的内存。
要获取进程的 ANON 内存明细,请运行以下命令:

cat /proc/<pid>/smaps

ION
ION 内存允许在视频、相机和 Linux 软件等硬件 IP 之间共享缓冲区。
ION 管理一个或多个内存池,这些内存池可以在启动时预留以应对内存碎片问题。
要检查 ION 内存的使用情况,请运行以下命令:

mount -t debugfs none /sys/kernel/debug
cat /sys/kernel/debug/dma_buf/bufinfo | grep bytes

KGSL
KGSL(Kernel Graphics Support Layer)是由图形驱动程序分配的内存。
要检查整体的 KGSL 内存使用情况,请运行以下命令:

cat /sys/class/kgsl/kgsl/page_alloc

要检查进程级别的内存明细,请运行以下命令:

cat /sys/class/kgsl/kgsl/proc/<pid>/kernel
未分配内存:

空闲内存是尚未使用且可供任何分配的内存。
要检查空闲内存,请运行以下命令:

cat /proc/meminfo | grep -i MemFree

实时内核 (Real-Time kernel)

实时 (RT) Linux 是一个可选功能,在 Qualcomm Linux 平台上默认未启用。可以根据产品需求启用。
RT Linux 旨在为时间敏感的应用程序提供确定性和可预测的行为。

设置工作区

在 Qualcomm Linux 中,RT Linux 内核配方被称为 linux-kernel-qcom-rt。
Qualcomm Linux 内核支持 v6.6 LTS RT 内核,该内核通过 Yocto 配方在 meta-qcom-realtime 层的 recipes-kernel/linux/linux-kernel-qcom-rt_6.6.bb 中维护。
有关如何克隆工作区并获取所有 meta 层以使用 Qualcomm RT Linux,请参见 How to sync and build with real-time Linux。

启用实时内核

通过使用 Linux RT 内核配方来启用 RT 内核。此配方获取内核、下载抢占 RT 补丁并将其应用于内核。它还启用一个完全可抢占的内核:

CONFIG_PREEMPT_RT=y

有关 RT 内核的更多信息,请参见 https://wiki.linuxfoundation.org/realtime/start。
最后,将以下配方添加到 recipes-kernel/linux/linux-kernel-qcom_6.6.bb 源代码中:

SECTION = "RT kernel"
SUMMARY = "Linux Real time kernel for QCOM devices"
DESCRIPTION = "Recipe to build real time Linux kernel"

SRC_URI:append = "https://cdn.kernel.org/pub/linux/kernel/projects/rt/6.6/older/patch-6.6.14-rt21.patch.gz;md5sum=91969a704a73aa918c89d3027bdd3634 \
                 file://qcom_rt.cfg \
                 file://0001-arch-Kconfig-Add-RT-kernel-support.patch \
                 file://0001-printk-nbcon-move-locked-port-flag-to-struct-uart-port.patch \
                 "

S = "${WORKDIR}/kernel"
KERNEL_CONFIG_FRAGMENTS:append = " ${WORKDIR}/qcom_rt.cfg"

优化 RT 内核

以下是一些优化 RT 内核性能的附加配置:

# CONFIG_NO_HZ
$ zcat /proc/config.gz | grep NO_HZ
CONFIG_NO_HZ_COMMON=y
# CONFIG_NO_HZ_IDLE is not set
CONFIG_NO_HZ_FULL=y
# CONFIG_NO_HZ is not set

# CONFIG_CPUSETS
$ zcat /proc/config.gz | grep CPUSETS
CONFIG_CPUSETS=y

当启用 CONFIG_NO_HZ_FULL 时,此配置会阻止向运行单个任务的 CPU 发送调度时钟中断。
CONFIG_CPUSETS 配置选项启用 CPUSETS 的使用,在这里,CPU 被分组到一个特定的集合中以运行一组特定的任务。
有关 CPUSET 的信息,请参见 https://docs.kernel.org/admin-guide/cgroup-v1/cpusets.html。

验证内核类型

启动后,可以通过运行以下命令来验证内核类型:

uname -v
SMP PREEMPT_RT。
  • 14
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值