> ## Documentation Index
> Fetch the complete documentation index at: https://dragonwingdocs-staging.qualcomm.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 运行时性能调优

Qualcomm<sup>®</sup> Linux 提供了用于运行时性能调优的 sysfs 接口、内核参数和设备树控制项。本页介绍 CPU 频率调节、内存子系统调优项、块 I/O 调度、Qualcomm 专有的 DCVS 与 DDR 带宽控制，以及硬件性能剖析。

## **CPU 性能调优**

### 选择 CPU 频率调节器

Qualcomm Linux 使用 schedutil 作为默认的 CPUFreq 调节器，并为每个 CPU 簇分配一个策略（policy）。簇的数量、CPU 与簇的映射关系以及核心类型均由目标平台决定。

**表：各目标平台的 CPU 簇映射**

<Tabs>
  <Tab title="QCS6490">
    | 簇   | CPU       | 核心类型       | `capacity-dmips-mhz` | cpufreq 策略 |
    | --- | --------- | ---------- | -------------------- | ---------- |
    | 小核  | cpu0–cpu3 | Cortex-A55 | 1024                 | `policy0`  |
    | 大核  | cpu4–cpu6 | Cortex-A78 | 1024                 | `policy1`  |
    | 超大核 | cpu7      | Cortex-A78 | 1024                 | `policy2`  |
  </Tab>

  <Tab title="IQ-9075">
    | 簇        | CPU       | `capacity-dmips-mhz` | cpufreq 策略 |
    | -------- | --------- | -------------------- | ---------- |
    | cluster0 | cpu0–cpu3 | 1024                 | `policy0`  |
    | cluster1 | cpu4–cpu7 | 1024                 | `policy1`  |

    两个簇使用相同的 capacity-dmips-mhz 值，因此 IQ-9075 是对称的双簇拓扑，而非小核/大核配置。Qualcomm Linux 将两个簇分开是为了实现独立的 DVFS 控制，而不是为了支持不同的核心性能等级。
  </Tab>

  <Tab title="IQ-8275">
    | 簇     | CPU       | 核心类型        | `capacity-dmips-mhz` | cpufreq 策略 |
    | ----- | --------- | ----------- | -------------------- | ---------- |
    | 小核    | cpu4–cpu7 | Cortex-A55  | 1024                 | `policy1`  |
    | 大核（A） | cpu0–cpu1 | Cortex-A78C | 1946                 | `policy0`  |
    | 大核（B） | cpu2–cpu3 | Cortex-A78C | 1946                 | `policy2`  |

    两组 Cortex-A78C 核心对运行在相互独立的频率域（policy0 和 policy2）上，因此每组核心都可以独立调整频率。
  </Tab>

  <Tab title="IQ-615">
    | 簇  | CPU       | 核心类型       | `capacity-dmips-mhz` | cpufreq 策略 |
    | -- | --------- | ---------- | -------------------- | ---------- |
    | 小核 | cpu0–cpu5 | Cortex-A55 | 1024                 | `policy0`  |
    | 大核 | cpu6–cpu7 | Cortex-A76 | 1740                 | `policy1`  |
  </Tab>
</Tabs>

每个目标平台都在其 SoC DTSI 的 CPU 节点中通过 qcom,freq-domain 和 capacity-dmips-mhz 属性定义此映射。有关各目标平台的 DTSI 文件路径，请参阅[定位并修改设备树](./locate-and-modify-device-trees)。

读取所有策略的当前调节器：

```bash theme={null}
cat /sys/devices/system/cpu/cpufreq/policy*/scaling_governor
```

更改所有策略的调节器：

```bash theme={null}
# Maximum throughput, disables frequency scaling
for p in /sys/devices/system/cpu/cpufreq/policy*/; do
    echo performance > "${p}scaling_governor"
done

# Restore adaptive scheduling
for p in /sys/devices/system/cpu/cpufreq/policy*/; do
    echo schedutil > "${p}scaling_governor"
done
```

**表：CPUfreq sysfs 频率控制项**

| sysfs 路径                           | 描述              |
| ---------------------------------- | --------------- |
| `cpufreq/policyN/scaling_max_freq` | 簇 N 的最大频率上限（Hz） |
| `cpufreq/policyN/scaling_min_freq` | 簇 N 的最小频率下限（Hz） |
| `cpufreq/policyN/scaling_cur_freq` | 当前选定的频率（只读）     |
| `cpufreq/policyN/cpuinfo_max_freq` | 硬件最大频率（只读）      |

路径相对于 `/sys/devices/system/cpu/`。

### 调整 schedutil 响应性

`rate_limit_us` 可调参数可防止 schedutil 以短于指定微秒间隔的频率更改频率。较低的值以更多的频率切换为代价提升响应性：

```bash theme={null}
echo 200 > /sys/devices/system/cpu/cpufreq/policy4/schedutil/rate_limit_us
```

有关能量感知调度（EAS）、利用率钳制（uclamp）和 CPU 拓扑的详细信息，请参阅 [配置调度器](./configure-the-scheduler)。

## **CPU 隔离与 IRQ 亲和性**

对于实时音频或确定性传感器流水线等对延迟敏感的工作负载，请将 CPU 从通用调度器中隔离出来，并将中断重定向到其他 CPU。

### 在启动时隔离 CPU

在内核命令行中添加以下参数：

```bash theme={null}
isolcpus=6,7 rcu_nocbs=6,7 nohz_full=6,7 irqaffinity=0-5
```

<Note>
  `isolcpus` 是静态的启动时机制。如需在不重启的情况下动态隔离 CPU，请使用 `cgroup cpuset`。
</Note>

### 在运行时配置 IRQ 亲和性

列出所有 IRQ 及其当前的 CPU 亲和性：

```bash theme={null}
for i in /proc/irq/*/smp_affinity_list; do
    echo "$i: $(cat $i)"
done
```

将特定 IRQ 移到指定 CPU：

```bash theme={null}
echo 4 > /proc/irq/<irq-number>/smp_affinity_list
```

替换以下内容：

* 将 `<irq-number>` 替换为 `/proc/interrupts` 中的中断号。

### 在隔离的 CPU 上运行进程

```bash theme={null}
taskset -c <cpu-list> <command>
```

替换以下内容：

* 将 `<cpu-list>` 替换为以逗号分隔或范围表示的 CPU 列表，例如 `6,7` 或 `4-7`。
* 将 `<command>` 替换为要执行的进程名称或路径。

更改正在运行进程的 CPU 亲和性：

```bash theme={null}
taskset -pc <cpu-list> <pid>
```

替换以下内容：

* 将 `<pid>` 替换为要修改的进程 ID。

## **内存性能调优**

### 透明大页（THP）

透明大页（THP）可为内存密集型工作负载降低 TLB 压力。默认的 Qualcomm 内核将 THP 设置为 `madvise` 模式（应用程序自行选择启用）。

```bash theme={null}
# Check current mode
cat /sys/kernel/mm/transparent_hugepage/enabled

# Enable system-wide
echo always > /sys/kernel/mm/transparent_hugepage/enabled

# Disable to reduce latency spikes from huge page allocation
echo never > /sys/kernel/mm/transparent_hugepage/enabled
```

所需 Kconfig：

```text theme={null}
CONFIG_TRANSPARENT_HUGEPAGE=y
CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y
```

### 虚拟内存 sysfs 调优项

**表：/proc/sys/vm 关键调优参数**

| 参数                          | 作用                                                                           |
| --------------------------- | ---------------------------------------------------------------------------- |
| `vm/swappiness`             | 控制换出匿名内存与回收页缓存之间的倾向。在内存受限的开发板上调低（10–20），以将匿名内存保留在 RAM 中。默认值：60。              |
| `vm/dirty_ratio`            | 在进程被限流写回之前，脏页可占用内存的最大百分比。写密集型工作负载可调高（30–40）。默认值：20。                          |
| `vm/dirty_background_ratio` | 后台写回开始时的百分比。默认值：10。                                                          |
| `vm/vfs_cache_pressure`     | 回收目录项（dentry）和 inode 的倾向。调低（50）以保留文件系统元数据缓存；对于 RAM 有限的嵌入式目标可调高（200）。默认值：100。 |
| `vm/min_free_kbytes`        | 内核开始回收的水位线。对于实时延迟需求可调高，以避免 OOM 引发的延迟尖峰。                                      |
| `vm/watermark_boost_factor` | 在分配压力激增后临时提高水位线。设为 0 可禁用。默认值：15000（150%）。                                    |

路径相对于 `/proc/sys/`。

### ZRAM 与 CMA

有关 ZRAM 交换配置和 CMA 区域调优，请参阅 [配置和管理内存](./configure-and-manage-memory)。

## **块 I/O 调优**

### 选择 I/O 调度器

Qualcomm 平台通常使用带多队列 blk-mq 的 UFS 或 eMMC 存储。查看所有块设备的当前调度器：

```bash theme={null}
for dev in /sys/block/*/queue/scheduler; do
    echo "$dev: $(cat $dev)"
done
```

**表：按存储类型推荐的 I/O 调度器**

| 存储类型 | 调度器              | 理由                                           |
| ---- | ---------------- | -------------------------------------------- |
| UFS  | `none`           | UFS 控制器自行处理命令排队（UFS Command Queue）。直通模式延迟最低。 |
| eMMC | `mq-deadline`    | 基于截止时间的排序可防止混合工作负载下读请求被饿死。                   |
| NVMe | `none` 或 `kyber` | 基于令牌桶的延迟目标控制对 SSD 很有效。                       |

为某个设备设置调度器：

```bash theme={null}
echo none > /sys/block/<device>/queue/scheduler
```

替换以下内容：

* 将 `<device>` 替换为块设备名称，例如 `sda`。

### 调整预读（read-ahead）

```bash theme={null}
# Increase for sequential workloads such as firmware update or logging
echo 512 > /sys/block/<device>/queue/read_ahead_kb

# Decrease for random access workloads such as databases
echo 128 > /sys/block/<device>/queue/read_ahead_kb
```

替换以下内容：

* 将 `<device>` 替换为块设备名称，例如 `sda`。

## **Qualcomm DCVS 与 DDR 带宽**

Qualcomm 动态时钟电压调节（DCVS）管理 L3/LLC 缓存、末级缓存控制器（LLCC）和 DDR 的频率。有两种机制驱动内存频率投票：将 CPU 频率与内存频率绑定的静态 OPP 表，以及基于实测总线流量进行投票的 BWMON 调节器。

### 静态 CPU 到内存映射

`qcom-cpufreq-hw` 驱动从 DTSI 中每个 CPU OPP 条目读取 `opp-peak-kBps`。当 CPU 以某一频率运行时，驱动会为对应的 L3 和 DDR 带宽投票。以下是 QCS6490 DTSI 中的示例条目：

```text theme={null}
cpu0_opp_1516mhz: opp-1516800000 {
    opp-hz       = /bits/ 64 <1516800000>;
    opp-peak-kBps = <5400000 51200000>;  /* DDR kBps, L3 kBps */
};
```

增大 `opp-peak-kBps` 值可在较低 CPU 频率下投票选择更高的内存频率，以功耗换取更低的内存延迟。驱动源码位于 `drivers/cpufreq/qcom-cpufreq-hw.c`。

### BWMON 调节器

`icc-bwmon` 驱动（`drivers/soc/qcom/icc-bwmon.c`）采样 CPU 到 LLCC 和 CPU 到 DDR 的带宽计数器，并据此发出 ICC 带宽投票。可在设备树中调整采样周期和阈值：

```text theme={null}
&bwmon_cpu {
    qcom,count-unit     = <0x1000>;  /* 4 KB per count */
    qcom,threshold-high = <400>;
    qcom,threshold-med  = <200>;
    qcom,threshold-low  = <50>;
    qcom,sample-ms      = <4>;       /* 4 ms sampling period */
};
```

在运行时监控当前的 ICC 带宽投票：

```bash theme={null}
cat /sys/kernel/debug/interconnect/interconnect_summary
```

有关 DVFS 调节器选择和缓存频率映射的详细信息，请参阅 [配置动态电压频率调节（DVFS）调节器](./configure-the-dynamic-voltage-and-frequency-scaling-dvfs-governors)。

## **硬件性能剖析**

ARM64 Qualcomm SoC 通过 ARM PMUv3 接口暴露硬件性能计数器。`perf` 工具利用这些计数器对 CPU 利用率、缓存未命中和内存停顿进行剖析。

### 所需 Kconfig

```text theme={null}
CONFIG_PERF_EVENTS=y
CONFIG_HW_PERF_EVENTS=y
CONFIG_ARM_PMU=y
CONFIG_QCOM_L2_PMU=y
CONFIG_QCOM_L3_PMU=y
```

### 采集系统级性能快照

```bash theme={null}
perf stat -a -e cycles,instructions,cache-misses,cache-references sleep 10
```

### 剖析特定进程

```bash theme={null}
perf record -g -p <pid> -- sleep 5
perf report
```

替换以下内容：

* 将 `<pid>` 替换为要剖析的进程 ID。

### Qualcomm L3 PMU 事件

Qualcomm L3 PMU 驱动以 `qcom_l3_cache/` 前缀暴露按切片（slice）划分的 L3 缓存事件：

```bash theme={null}
perf stat -e qcom_l3_cache/event=0x21/ -a sleep 5
```

### 使用 perf top 进行实时剖析

```bash theme={null}
perf top -g --call-graph dwarf
```
