# 影响性能的功能

Qualcomm^®^ Linux^®^ 内核包括 CPU 调度器、CPU 频率调节器、动态电压和频率调节 (DVFS) 以及内存管理等功能。本指南概述了每个功能并提供了相关参考链接。此外，Qualcomm 还增加了一项名为 PerfHAL 的功能，以增强 Qualcomm Linux 的性能。

## CPU 调度器

CPU 调度器用于管理 CPU 时间如何在 Linux 系统上运行的进程之间分配。

它使用 EEVDF（最早符合条件的虚拟截止时间优先）调度器，这是 Linux 内核提供的一种功能。EEVDF CPU 调度器使用 “每实体负载跟踪” (PELT) 来监测任务的负载。

如需了解更多信息，请访问：

- [An EEVDF CPU scheduler for Linux](https://lwn.net/Articles/925371/)
- [Per-entity load tracking \[LWN.net\]](https://lwn.net/Articles/531853/)

利用率限制（UCLAMP 或 util\_clamp）是一项调度器功能，可帮助管理任务的性能要求。

如需了解更多信息，请访问：

- [Utilization Clamping](https://docs.kernel.org/scheduler/sched-util-clamp.html)
- [定制 CPU 调度器](https://docs.qualcomm.com/doc/80-70022-10SC/topic/18-customize.html#customize-scheduler)

## CPU 频率调节器

CPU 频率调节器根据任务负载调整 CPU 频率。CPU 调度器为该进程提供必要的输入。

Qualcomm Linux 使用 Linux 内核提供的 `schedutil` 调节器功能。

该调节器可在系统承受高负载时提高频率，在负载减少时降低频率，从而确保达到功耗与性能之间的最佳平衡。

如需了解更多信息，请访问：

- [CPU frequency and voltage scaling code in the Linux kernel](https://www.kernel.org/doc/Documentation/cpu-freq/governors.txt)
- [配置 CPU](https://docs.qualcomm.com/doc/80-70022-10SC/topic/14-configure.html#cpu)
- [定制 CPU 频率调节器](https://docs.qualcomm.com/doc/80-70022-10SC/topic/18-customize.html#cpu-frequency-governer)

## DVFS 调节器

DVFS 调节器根据系统工作负载控制 CPU 缓存 (L3)、最后一级缓存控制器 (LLCC) 和 DDR 的频率。

这些调节器可在高工作负载时提高频率，在低工作负载时降低频率，从而确保在功耗与性能之间达到最佳平衡。

Qualcomm Linux 支持以下两种 L3 缓存的 DVFS 调节器：

- LLCC
- DDR

### 静态映射 DVFS 调节器

该调节器确保 CPU L3 缓存和 DDR 的频率与当前 CPU 频率保持一致，以平衡功耗和性能要求。

例如，如果 CPU 频率达到最大值，则 L3 缓存和 DDR 频率也必须达到最大值。

静态映射位于 `arch/arm64/boot/dts/qcom/<target>.dtsi` 的源代码中。

关于定制选项，请参阅[定制静态映射 DVFS 调节器](https://docs.qualcomm.com/doc/80-70022-10SC/topic/18-customize.html#section-u1x-jps-51c-caharris-03-20-24-2005-37-832)。

### BWMON 调节器

带宽监控 (BWMON) 调节器根据测得的从 CPU 流向 LLCC 再流向 DDR 的流量，动态调整 LLCC 和 DDR 的频率。

BWMON 硬件模块测量此流量。该模块在指定采样窗口内监测内存与其他子系统之间的数据吞吐量，并利用这一信息来调整 LLCC 和 DDR 频率，以满足所需带宽。

BWMON 调节器驱动程序的源代码位于 `drivers/soc/qcom/icc-bwmon.c`。

如需了解更多信息，请访问：

- [\[PATCH v3 0/4\] soc/arm64: qcom: Add initial version of bwmon](https://lwn.net/ml/linux-kernel/20220531105137.110050-1-krzysztof.kozlowski@linaro.org/)
- [定制 BWMON 调节器](https://docs.qualcomm.com/doc/80-70022-10SC/topic/18-customize.html#section-qxs-4ps-51c-caharris-03-20-24-2007-2-926)

## 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)`

表： perf_lock_acq API 参数

| 参数 | 说明 |
| --- | --- |
| `handle` | 标识客户端请求。 |
| `duration` | <ul class="simple"><br><li><p>表示需要锁定 perflock 的最长时间（单位为毫秒）。</p></li><br><li><p><code class="docutils literal notranslate"><span class="pre">duration</span></code> 参数可以设置为有限时间或无限时间 <code class="docutils literal notranslate"><span class="pre">(0)</span></code>。</p><ul><br><li><p>有限时间 perflock 需要用一个正整数值来指定最长锁定持续时间。将创建一个定时器，定时器达到定时值时便会释放 perflock</p></li><br><li><p>无限时间 perflock 将持续锁定到客户端调用释放函数为止。请使用 <code class="code docutils literal notranslate"><span class="pre">perf_lock_rel()</span></code> 函数，以便手动释放已设置为无限时间的 perflock。</p></li><br></ul><br></li><br></ul> |
| `list` | 资源操作码和值对的数组。操作码指示系统参数（资源）和设置值（级别）。 |
| `numArgs` | list 数组中的参数个数。 |

表：perf_lock_acq API 返回值和结果

| 返回值 | 结果 |
| --- | --- |
| 非零整数 | 成功 |
| -1 | 失败 |

### Perflock 释放

`perf_lock_rel()` 函数用于释放 `perf_lock_acq()` API 锁定的 perflock。此功能仅用于设置为无限时间的 perflock。该函数的语法如下：

`int perf_lock_rel(int handle)`

表： perf_lock_rel API 参数

| 参数 | 说明 |
| --- | --- |
| `handle` | <ul class="simple"><br><li><p>跟踪唯一请求</p></li><br><li><p>传递 <code class="docutils literal notranslate"><span class="pre">perf_lock_acq()</span></code> 返回的相同句柄以释放锁</p></li><br></ul> |

表：perf_lock_rel API 返回值和结果

| 返回值 | 结果 |
| --- | --- |
| 非零整数 | 成功 |
| -1 | 失败 |

### 资源操作码

Perflock 使用操作码及其相应值的组合对 perflock 资源执行特定操作。

要了解 Qualcomm Dragonwing^™^ IQ-9075、Qualcomm Dragonwing^™^ IQ-8275 和 Qualcomm Dragonwing^™^ IQ-615 支持的操作码，请参阅相应的附录。以下指南可供具有授权访问权限的许可用户使用：

- [Qualcomm Linux Performance Guide - Addendum for Qualcomm Dragonwing IQ-9075](https://docs.qualcomm.com/bundle/resource/topics/80-70022-10A/overview.html)
- [Qualcomm Linux Performance Guide - Addendum for Qualcomm Dragonwing IQ-8275](https://docs.qualcomm.com/bundle/resource/topics/80-70022-10B/overview.html)
- [Qualcomm Linux Performance Guide - Addendum for Qualcomm Dragonwing IQ-615](https://docs.qualcomm.com/bundle/resource/topics/80-70022-10C/overview.html)

下表列出了支持的操作码：

表：支持的操作码

| 操作码 | 目的 | 设备上的系统节点 |
| --- | --- | --- |
| 0x44000000 | 设置单个任务和任务组可接受的最低性能级别。 | `/proc/sys/kernel/sched_util_clamp_min` |
| 0x44004000 | 设置单个任务和任务组可接受的最高性能级别。 | `/proc/sys/kernel/sched_util_clamp_max` |
| 0x44008100 | 设置小核群集的最低频率。 | `/sys/devices/system/cpu/cpufreq/policy0/scaling_min_freq` |
| 0x44008000 | 设置大核群集的最低频率。 | `/sys/devices/system/cpu/cpufreq/policy4/scaling_min_freq` |
| 0x44008200 | 设置超大核群集的最低频率。 | `/sys/devices/system/cpu/cpufreq/policy7/scaling_min_freq` |
| 0x4400C100 | 设置小核群集的最高频率。 | `/sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq` |
| 0x4400C000 | 设置大核群集的最高频率。 | `/sys/devices/system/cpu/cpufreq/policy4/scaling_max_freq` |
| 0x4400C200 | 设置超大核群集的最高频率。 | `/sys/devices/system/cpu/cpufreq/policy7/scaling_max_freq` |

以下是资源操作码的一些示例：

- 0x44008100, 1958400：这一对操作码和值表示小核群集的最低频率必须设置为 1958400 KHz。
- 0x44008100, 1958400, 0x4400C100, 2100000：这一对操作码和值表示小核群集的最低频率必须设置为 1958400 KHz。小核群集的最高频率必须设置为 2100000 KHz。

有关如何使用和调试 perflock 的更多信息，参见[定制 perflock](https://docs.qualcomm.com/doc/80-70022-10SC/topic/18-customize.html#customize-perlocks)。

## 内存

Qualcomm Linux 的所有内存分配均使用 RAM。必须对 RAM 进行管理，以满足性能需求并确保应用程序的顺畅运行。下图显示了内存分区：

<!--?xml version="1.0" encoding="UTF-8"?-->
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" width="600" height="342.9" version="1.1" viewbox="0 0 600 342.9" aria-label="../../_images/memory_partitioning.svg">
  <!-- Generator: Adobe Illustrator 29.5.0, SVG Export Plug-In . SVG Version: 2.1.0 Build 137)  -->
  <defs>
    <style>.svg-1 .st0 { font-family: Roboto-Bold, Roboto; font-size: 18px; font-weight: 700 }
.svg-1 .st0,.svg-1 .st1,.svg-1 .st2,.svg-1 .st3 { isolation: isolate }
.svg-1 .st4,.svg-1 .st2 { font-family: Roboto-Medium, Roboto; font-weight: 500 }
.svg-1 .st5 { fill: #007884 }
.svg-1 .st1,.svg-1 .st2,.svg-1 .st3 { font-size: 16px }
.svg-1 .st6 { fill: #d2d7e1 }
.svg-1 .st7 { stroke-dasharray: 5 }
.svg-1 .st7,.svg-1 .st8,.svg-1 .st9 { fill: none; stroke: #7c8aa3; stroke-miterlimit: 10 }
.svg-1 .st8 { stroke-dasharray: 5 5 }
.svg-1 .st10,.svg-1 .st3 { font-family: SimHei, SimHei }
.svg-1 .st11 { font-family: Roboto-Regular, Roboto }
.svg-1 .st3 { fill: #fff }
.svg-1 .st12 { fill: #fafafa }</style>
  </defs>
  <g>
    <rect class="st12" x=".5" y=".5" width="599" height="341.9" rx="7.5" ry="7.5"></rect>
    <path class="st6" d="M592,1c3.9,0,7,3.1,7,7v326.9c0,3.9-3.1,7-7,7H8c-3.9,0-7-3.1-7-7V8c0-3.9,3.1-7,7-7h584M592,0H8C3.6,0,0,3.6,0,8v326.9c0,4.4,3.6,8,8,8h584c4.4,0,8-3.6,8-8V8c0-4.4-3.6-8-8-8h0Z"></path>
  </g>
  <rect class="st5" x="44.3" y="65.6" width="140.2" height="201.2" rx="4" ry="4"></rect>
  <rect class="st5" x="243.3" y="99.2" width="148.9" height="76" rx="4" ry="4"></rect>
  <rect class="st5" x="406.8" y="99.2" width="148.9" height="76" rx="4" ry="4"></rect>
  <rect class="st5" x="243.3" y="190.9" width="148.9" height="76" rx="4" ry="4"></rect>
  <rect class="st5" x="406.8" y="190.9" width="148.9" height="76" rx="4" ry="4"></rect>
  <rect class="st7" x="15" y="36.4" width="570" height="291.5" rx="4" ry="4"></rect>
  <g>
    <line class="st9" x1="213.8" y1="36.4" x2="213.8" y2="38.9"></line>
    <line class="st8" x1="213.8" y1="43.9" x2="213.8" y2="322.9"></line>
    <line class="st9" x1="213.8" y1="325.4" x2="213.8" y2="327.9"></line>
  </g>
  <text class="st0" transform="translate(544.8 28.3)"><tspan x="0" y="0">RAM</tspan></text>
  <text class="st1" transform="translate(316.4 84.8)"><tspan class="st10" x="0" y="0">内存总量（系统</tspan><tspan class="st11" x="112" y="0" xml:space="preserve"> RAM</tspan><tspan class="st10" x="150.2" y="0">）</tspan></text>
  <text class="st3" transform="translate(285.7 144.1)"><tspan x="0" y="0">静态内核</tspan></text>
  <text class="st3" transform="translate(449.2 144.1)"><tspan x="0" y="0">动态内核</tspan></text>
  <text class="st3" transform="translate(449.2 235.7)"><tspan x="0" y="0">空闲内存</tspan></text>
  <text class="st3" transform="translate(269.7 235.7)"><tspan x="0" y="0">用户空间进程</tspan></text>
  <text class="st3" transform="translate(98.4 171.1)"><tspan x="0" y="0">预留</tspan></text>
  <text class="st2" transform="translate(243.3 313.1)"><tspan x="0" y="0">Linux</tspan></text>
  <text class="st1" transform="translate(125.9 313.2)"><tspan class="st10" x="0" y="0">非</tspan><tspan class="st4" x="16" y="0" xml:space="preserve"> Linux</tspan></text>
</svg>

**图：内存分区**

该图展示了支持 Linux 和非 Linux 环境的系统中的 RAM 分配情况。

- 系统 RAM 在非 Linux 和 Linux 组件之间进行分区。
- 非 Linux 部分包含一个标有“保留”的大块，表示为非 Linux 操作分配的内存。
- Linux 部分在总内存（系统 RAM）下分为四个块：

    - 静态内核
    - 动态内核
    - 用户空间进程
    - 空闲内存

RAM 的某些部分独立于 Linux 系统进行管理。例如，从这些特定 RAM 分区运行的 Modem、视频和音频等固件。Linux 内核管理所有其他 RAM 分区。

Linux 内核有自己的内存管理子系统，其中包括：

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

### RAM 内存分区

下表描述了各种类型的内存分配。

Note

应在设备上运行下表中指定的命令。

| RAM 分类 | 内存段 | 分配类型 | 说明 |
| --- | --- | --- | --- |
| 非 Linux | – | – | <ul class="simple"><br><li><p>内存以 carveout 的形式由 Linux 以外的各种子系统保留。</p></li><br><li><p>这些 carveout  在相应 DTSI 文件中指定。</p></li><br></ul> |
| Linux（系统 RAM） | 静态内核 | Vmlinux + 内核页结构 | <ul><br><li><p>内核在启动时保留该内存供自己使用。</p></li><br><li><p>Vmlinux 内存用于存储 vmlinux 镜像。</p></li><br><li><p>Vmlinux 镜像的大小和细分情况，可以从启动时的 <code class="docutils literal notranslate"><span class="pre">dmesg</span></code> 日志中获取：</p><br><blockquote><br><div><p>Memory: 3061872K/4134912K available (28800K kernel code, 2090K rwdata, 10688K rodata, 3072K init, 969K bss, 679824K reserved, 393216K cma-reserved)</p><br><p>Kernel code + rwdata + rodata + init +bss indicates vmlinux kernel image size (28800k + 2090k + 10688k + 3072k + 969k)</p><br></div></blockquote><br></li><br><li><p>内核页结构是内核在维护每一个 RAM 页的结构时所使用的内存。其计算方法为每 GB RAM 为 16 MB。</p></li><br></ul> |
| Linux（系统 RAM） | 动态内核 | Slab | <ul class="simple"><br><li><p>Slab 由内核使用，旨在提高常用数据结构使用内存的速度和效率。</p></li><br><li><p>要查看 slab 的内存使用情况，请运行以下命令：</p></li><br></ul><br><br>cat /proc/meminfo | grep -i slab<br>    Copy to clipboard<br><ul class="simple"><br><li><p>要查看各种 slab 的细分及用法，可在内核配置中启用 <code class="docutils literal notranslate"><span class="pre">CONFIG_SLUB_DEBUG</span></code>，然后运行以下命令：</p></li><br></ul><br><br>cat /proc/slabinfo<br>    Copy to clipboard |
| Linux（系统 RAM） | 动态内核 | 内核堆栈 | <ul class="simple"><br><li><p>内核堆栈存储每个进程的调用堆栈。</p></li><br><li><p>要查看内核协议栈的内存使用情况，请运行以下命令：</p></li><br></ul><br><br>cat /proc/meminfo | grep -i kernelstack<br>    Copy to clipboard |
| Linux（系统 RAM） | 动态内核 | PageTables | <ul class="simple"><br><li><p>内核使用内存来存储将虚拟地址映射到物理地址的 PageTables</p></li><br><li><p>要查看 PageTables 的内存使用情况，请运行以下命令：</p></li><br></ul><br><br>cat /proc/meminfo | grep -i PageTables<br>    Copy to clipboard |
| Linux（系统 RAM） | 动态内核 | 模块 | <ul class="simple"><br><li><p>以内核模块的形式表示动态加载到内核中的内核实体。</p></li><br><li><p>要显示已加载内核模块的列表及其内存使用情况，可运行以下命令：</p></li><br></ul><br><br>cat /proc/modules<br>    Copy to clipboard |
| Linux（系统 RAM） | 动态内核 | Vmalloc | <ul class="simple"><br><li><p>用于分配连续内存。</p></li><br><li><p>要查看 Vmalloc 内存细分，请运行以下命令：</p></li><br></ul><br><br>cat /proc/vmallocinfo<br>    Copy to clipboard |
| Linux（系统 RAM） | 动态内核 | 缓存（内核 + 用户空间） | <ul class="simple"><br><li><p>驻留在 RAM 中的由文件支持的内存量。</p></li><br><li><p>要查看缓存内存使用情况，请运行以下命令：</p></li><br></ul><br><br>cat /proc/meminfo | grep -i cached<br>    Copy to clipboard |
| Linux（系统 RAM） | 动态内核 | 缓冲区 | <ul class="simple"><br><li><p>缓冲区的大小固定，包含从磁盘读取或写入磁盘的信息块。</p></li><br><li><p>要查看缓存内存使用情况，请运行以下命令：</p></li><br></ul><br><br>cat /proc/meminfo | grep -i Buffers<br>    Copy to clipboard |
| Linux（系统 RAM） | 动态内核 | Shmem | <ul class="simple"><br><li><p>共享内存是映射到两个或多个进程的地址空间的公共内存块。</p></li><br><li><p>要查看共享内存使用情况，请运行以下命令：</p></li><br></ul><br><br>cat /proc/meminfo | grep -i shmem<br>    Copy to clipboard |
| Linux（系统 RAM） | 用户空间 | ZUSED (ZRAM) | 由 ZRAM 进行后压缩的匿名内存。 |
| Linux（系统 RAM） | 用户空间 | CMA | <ul class="simple"><br><li><p>连续物理内存通常映射到其他 IP，如视频和显示。但会分配给 runtime。</p></li><br><li><p>随着使用更多的 CMA 预留，系统可以使用的可用内存会减少。只有可移动分配（例如用户空间进程分配）才能使用 CMA 保留的可用内存。但不能用于内核分配。</p></li><br></ul> |
| Linux（系统 RAM） | 用户空间 | ANON | <ul class="simple"><br><li><p>用户空间应用程序使用 <code class="docutils literal notranslate"><span class="pre">malloc()</span></code> 或 <code class="docutils literal notranslate"><span class="pre">new()</span></code> 函数调用分配的内存。</p></li><br><li><p>要查看进程的 ANON 内存细分，请运行以下命令：</p></li><br></ul><br><br><br>> <br>> <br>> cat /proc/<pid>/smaps<br>>     Copy to clipboard |
| Linux（系统 RAM） | 用户空间 | ION | <ul class="simple"><br><li><p>ION 内存允许在硬件 IP（如视频、摄像头和 Qualcomm Linux）之间共享缓存。</p></li><br><li><p>ION 管理一个或多个内存池，这些内存池在启动时可以预留出来以防止碎片化。</p></li><br><li><p>要查看 ION 内存使用情况，请运行以下命令：</p></li><br></ul><br><br>mount -t debugfs none /sys/kernel/debug<br>    Copy to clipboard<br><br><br>cat /sys/kernel/debug/dma_buf/bufinfo | grep bytes<br>    Copy to clipboard |
| Linux（系统 RAM） | 用户空间 | KGSL | <ul class="simple"><br><li><p>图形驱动程序分配的内存。</p></li><br><li><p>要创建整体内核图形支持层 (KGSL) 内存使用情况，请运行以下命令：</p></li><br></ul><br><br><br>> <br>> <br>> cat /sys/class/kgsl/kgsl/page_alloc<br>>     Copy to clipboard<br><br><ul class="simple"><br><li><p>要查看进程级别细分，请运行以下命令：</p></li><br></ul><br><br><br>> <br>> <br>> cat /sys/class/kgsl/kgsl/proc/<pid>/kernel<br>>     Copy to clipboard |
| Linux（系统 RAM） | 空闲内存 | – | <ul><br><li><p>空闲内存是指尚未使用并可用于任何分配的内存。</p></li><br><li><p>要查看可用内存，请运行以下命令：</p><br><div class="highlight-default notranslate"><div class="highlight"><pre class="pre codeblock"><code>cat /proc/meminfo | grep -i MemFree<br></code><span class="copyclip"><svg xmlns="http://www.w3.org/2000/svg" class="copyclipicon" width="25px" height="25px" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><title>Copy to clipboard</title><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg></span></pre></div><br></div><br></li><br></ul> |
|  |  |  |  |
|  |  |  |  |
|  |  |  |  |
|  |  |  |  |
|  |  |  |  |
|  |  |  |  |
|  |  |  |  |
|  |  |  |  |
|  |  |  |  |
|  |  |  |  |
|  |  |  |  |
|  |  |  |  |
|  |  |  |  |
|  |  |  |  |

## 实时内核

实时 (RT) Linux 是一个可选功能，默认情况下在 Qualcomm Linux 平台上不启用。可以根据产品要求启用该功能。

RT Linux 旨在为时间敏感型应用提供确切并且可预测的行为。

### 设置工作区

在 Qualcomm Linux 中，RT Linux 内核配方参考如下：

- 基础 BSP：`linux-qcom-base-rt`
- 定制 BSP：`linux-qcom-custom-rt`

Qualcomm Linux 内核支持 长期支持( LTS）RT 内核 6.6 版本，通过源代码中以下路径的 `meta-qcom-realtime` 层中的 Yocto 配方进行维护：

- 基础 BSP：`recipes-kernel/linux/linux-kernel-base-rt_6.6.bb`
- 定制 BSP：`recipes-kernel/linux/linux-kernel-custom-rt_6.6.bb`

关于如何克隆工作区并获取所有元层以使用 Qualcomm RT Linux 内核的更多信息，请参阅[使用实时 Linux 同步和构建](https://docs.qualcomm.com/bundle/publicresource/topics/80-70022-254/how_to.html#sync-and-build-with-real-time-linux)。

### 启用 RT 内核

使用 RT Linux 内核配方来启用 RT 内核。该配方获取内核，下载抢占 RT 补丁，并将这些补丁应用于内核。它还可以通过以下配置启用可完全抢占的内核：

`CONFIG_PREEMPT_RT=y`

如需了解更多信息，请参阅[实时 (RT) 内核概述](https://docs.qualcomm.com/bundle/publicresource/topics/80-70022-3/real_time_kernel_overview.html)。

### 验证内核类型

启动后，通过在设备上运行以下命令来验证内核类型：

uname -v
    Copy to clipboard

以下是命令的输出：

SMP PREMPT\_RT

### 测试 RT Linux 内核

RT Linux 内核测试可获取以下信息：

- RT Linux 内核的实时性能
- RT Linux 内核延迟和关键性能指标 (KPI)

Note

本节仅适用于 QCS6490。

Caution

请勿在 RT Linux 内核测试期间重启系统，因为该测试会持续运行 24 小时以上。

### cyclictest

cyclictest 工具用于对 RT Linux 内核系统进行基准测试。它用于评估实时系统的相对性能。Qualcomm Linux 编译版本包含 cyclictest 工具。如需了解更多信息，请参阅 [cyclictest](https://wiki.linuxfoundation.org/realtime/documentation/howto/tools/cyclictest/start)。

本指南介绍以下内容：

- 无负载的 cyclictest：不添加系统负载来执行此测试。
- 结合 stress-ng（下一代）的 cyclictest：添加特定百分比的负载来执行此测试，以测量最坏情况下的系统延迟。有关 stress-ng 的更多信息，请参阅 [Ubuntu Wiki - stress-ng](https://wiki.ubuntu.com/Kernel/Reference/stress-ng/)。

#### cyclictest 的先决条件

> 
> 
> 运行 cyclictest 之前，确保满足以下先决条件：

1. 配置并隔离 CPU 核心 1 至核心 3 以执行 RT 任务。用户可以根据需要配置任何其他 CPU 内核。

    例如，您可以在以下路径的源代码中配置 RT CPU：

    `layers/meta-qcom-realtime/blob/scarthgap/conf/layer.conf`

    例如，CPU 配置如下：

KERNEL_CMDLINE_EXTRA:qcm6490 = "pcie_pme=nomsi net.ifnames=0 pci=noaer kpti=off kasan=off kasan.stacktrace=off swiotlb=128 mitigations=auto kernel.sched_pelt_multiplier=4 rcupdate.rcu_expedited=1 rcu_nocbs=1-3 isolcpus=1-3 irqaffinity=4-7 nohz_full=1-3 no-steal-acc vfio_iommu_type1.allow_unsafe_interrupts=1"
        Copy to clipboard
2. 在 RT Linux 内核上运行以下命令：

> 
> 
> echo 0 > /sys/kernel/tracing/tracing_on
>         Copy to clipboard
> 
> 
> echo E0 > /sys/devices/virtual/workqueue/kgsl-workqueue/cpumask
>         Copy to clipboard
> 
> 
> echo E0 > /sys/devices/virtual/workqueue/scsi_tmf_0/cpumask
>         Copy to clipboard
> 
> 
> echo E0 > /sys/devices/virtual/workqueue/writeback/cpumask
>         Copy to clipboard
> 
> 
> echo 1 > /sys/devices/system/cpu/cpu0/cpuidle/state0/disable
>         Copy to clipboard
> 
> 
> echo 1 > /sys/devices/system/cpu/cpu0/cpuidle/state1/disable
>         Copy to clipboard
> 
> 
> echo 1 > /sys/devices/system/cpu/cpu0/cpuidle/state2/disable
>         Copy to clipboard
> 
> 
> echo 1 > /sys/devices/system/cpu/cpu1/cpuidle/state0/disable
>         Copy to clipboard
> 
> 
> echo 1 > /sys/devices/system/cpu/cpu1/cpuidle/state1/disable
>         Copy to clipboard
> 
> 
> echo 1 > /sys/devices/system/cpu/cpu1/cpuidle/state2/disable
>         Copy to clipboard
> 
> 
> echo 1 > /sys/devices/system/cpu/cpu2/cpuidle/state0/disable
>         Copy to clipboard
> 
> 
> echo 1 > /sys/devices/system/cpu/cpu2/cpuidle/state1/disable
>         Copy to clipboard
> 
> 
> echo 1 > /sys/devices/system/cpu/cpu2/cpuidle/state2/disable
>         Copy to clipboard
> 
> 
> echo 1 > /sys/devices/system/cpu/cpu3/cpuidle/state0/disable
>         Copy to clipboard
> 
> 
> echo 1 > /sys/devices/system/cpu/cpu3/cpuidle/state1/disable
>         Copy to clipboard
> 
> 
> echo 1 > /sys/devices/system/cpu/cpu3/cpuidle/state2/disable
>         Copy to clipboard
> 
> 
> echo 1 > /sys/devices/system/cpu/cpu4/cpuidle/state0/disable
>         Copy to clipboard
> 
> 
> echo 1 > /sys/devices/system/cpu/cpu4/cpuidle/state1/disable
>         Copy to clipboard
> 
> 
> echo 1 > /sys/devices/system/cpu/cpu4/cpuidle/state2/disable
>         Copy to clipboard
> 
> 
> echo 1 > /sys/devices/system/cpu/cpu5/cpuidle/state0/disable
>         Copy to clipboard
> 
> 
> echo 1 > /sys/devices/system/cpu/cpu5/cpuidle/state1/disable
>         Copy to clipboard
> 
> 
> echo 1 > /sys/devices/system/cpu/cpu5/cpuidle/state2/disable
>         Copy to clipboard
> 
> 
> echo 1 > /sys/devices/system/cpu/cpu6/cpuidle/state0/disable
>         Copy to clipboard
> 
> 
> echo 1 > /sys/devices/system/cpu/cpu6/cpuidle/state1/disable
>         Copy to clipboard
> 
> 
> echo 1 > /sys/devices/system/cpu/cpu6/cpuidle/state2/disable
>         Copy to clipboard
> 
> 
> echo 1 > /sys/devices/system/cpu/cpu7/cpuidle/state0/disable
>         Copy to clipboard
> 
> 
> echo 1 > /sys/devices/system/cpu/cpu7/cpuidle/state1/disable
>         Copy to clipboard
> 
> 
> echo 1 > /sys/devices/system/cpu/cpu7/cpuidle/state2/disable
>         Copy to clipboard
> 
> 
> echo performance > /sys/devices/system/cpu/cpufreq/policy7/scaling_governor
>         Copy to clipboard
> 
> 
> echo performance  > /sys/devices/system/cpu/cpufreq/policy4/scaling_governor
>         Copy to clipboard
> 
> 
> echo performance > /sys/devices/system/cpu/cpufreq/policy0/scaling_governor
>         Copy to clipboard
> 
> 
> echo +cpuset > /sys/fs/cgroup/cgroup.subtree_control
>         Copy to clipboard
> 
> 
> mkdir /sys/fs/cgroup/cpuset
>         Copy to clipboard
> 
> 
> echo +cpuset > /sys/fs/cgroup/cpuset/cgroup.subtree_control
>         Copy to clipboard

> 
> 
> - 空载 cyclictest
>     - 要在空载情况下运行 cyclictest，请按照下列步骤操作：
> 
> 1. 满足[先决条件](https://docs.qualcomm.com/doc/80-70022-10SC/topic/2-performance-features.html#prerequisites-for-cyclictest)。
> 2. 运行以下命令启动循环测试：
> 
> 
> > 
> > 
> > mkdir /sys/fs/cgroup/cpuset/core1-3/
> >         Copy to clipboard
> 
> 
> 
> echo +cpuset > /sys/fs/cgroup/cpuset/core1-3/cgroup.subtree_control
>         Copy to clipboard
> 
> 
> echo 1-3 > /sys/fs/cgroup/cpuset/core1-3/cpuset.cpus
>         Copy to clipboard
> 
> 
> echo $$ > /sys/fs/cgroup/cpuset/core1-3/cgroup.procs
>         Copy to clipboard
> 
> 
> cyclictest -a 1-3 -t 3 -m -l 100000000 -i 1000 -p 90 -h 800 --mainaffinity 4 --spike 100
>         Copy to clipboard
> 3. 记录延迟。
> 
> - stress-ng 和 cyclictest 结合使用
>     - stress-ng 和 cyclictest 结合使用，请按照下列步骤操作：
> 
> 
> 
> 1. 满足[先决条件](https://docs.qualcomm.com/doc/80-70022-10SC/topic/2-performance-features.html#prerequisites-for-cyclictest)。
> 2. 打开 shell 并运行以下命令来运行 stress-ng。在第二个示例命令中，非 RT CPU 的负载为 60%：
> 
> 
> 
> > 
> > 
> > mkdir /tmp/temp-path
> >         Copy to clipboard
> 
> 
> 
> > 
> > 
> > stress-ng --cpu 5 --cpu-load 60 --temp-path /tmp/temp-path --sched fifo --sched-prio 1 -t 2d
> >         Copy to clipboard
> 
> 
> 
> 此过程大约需要 48 小时才能完成。在此示例中，已加载 CPU 1、4 和 7。
> 3. 同时运行 cyclictest 和 stress-ng。运行以下命令，在另一个终端中启动 cyclictest：
> 
> 
> 
> > 
> > 
> > mkdir /sys/fs/cgroup/cpuset/core1-3/
> >         Copy to clipboard
> 
> 
> 
> > 
> > 
> > echo +cpuset > /sys/fs/cgroup/cpuset/core1-3/cgroup.subtree_control
> >         Copy to clipboard
> 
> 
> 
> echo 1-3 > /sys/fs/cgroup/cpuset/core1-3/cpuset.cpus
>         Copy to clipboard
> 
> 
> echo $$ > /sys/fs/cgroup/cpuset/core1-3/cgroup.procs
>         Copy to clipboard
> 
> 
> cyclictest -a 1-3 -t 3 -m -l 100000000 -i 1000 -p 90 -h 800 --mainaffinity 4 --spike 100
>         Copy to clipboard
> 4. 按 Ctrl + C 停止 stress-ng。
> 5. 记录最坏情况下的延迟。

### RT Linux 内核关键性能指标

下表对 cyclictest KPI 进行了描述

空载 cyclictest 的 KPI

| RT 线程 | 优先级 | 最小延迟（以微秒为单位） | 最大延迟（以微秒为单位） |
| --- | --- | --- | --- |
| T0 | 90 | 9 | 72 |
| T1 | 90 | 9 | 62 |
| T2 | 90 | 9 | 63 |

结合使用 strss-ng 和 cyclictest 的 KPI

| RT 线程 | 优先级 | 最小延迟（以微秒为单位） | 最大延迟（以微秒为单位） |
| --- | --- | --- | --- |
| T0 | 90 | 9 | 71 |
| T1 | 90 | 9 | 73 |
| T2 | 90 | 9 | 73 |

## 后续步骤

- [为性能调优而定制](https://docs.qualcomm.com/doc/80-70022-10SC/topic/18-customize.html#customize)
- [性能分析工具](https://docs.qualcomm.com/doc/80-70022-10SC/topic/13-performance_tools.html#performance-tools)

Last Published: Nov 02, 2025

[Previous Topic
开始性能调优和优化](https://docs.qualcomm.com/bundle/publicresource/80-70022-10SC/topics/get-started.md) [Next Topic
性能分析工具](https://docs.qualcomm.com/bundle/publicresource/80-70022-10SC/topics/13-performance_tools.md)

Source: [https://docs.qualcomm.com/doc/80-70022-10SC/topic/2-performance-features.html](https://docs.qualcomm.com/doc/80-70022-10SC/topic/2-performance-features.html)