> ## 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<sup>®</sup> 内核包含 CPU 调度器、CPU 频率调速器、动态电压和频率调节（DVFS）以及内存管理等功能。本指南概述了每个功能及相关参考链接。此外，Qualcomm 使用一项名为 Userspace Resource Manager（URM）的功能来增强 Qualcomm Linux 的性能。

## **了解 CPU 调度器**

CPU 调度器管理 CPU 时间在 Linux 系统上运行的进程之间的分配方式。

CPU 调度器使用 Linux 内核提供的 [An earliest eligible virtual deadline first (EEVDF) CPU scheduler for Linux](https://lwn.net/Articles/925371/)。EEVDF CPU 调度器使用 [Per-entity load tracking \[](https://lwn.net/Articles/531853/)[LWN.net](http://LWN.net)[\]](https://lwn.net/Articles/531853/) 来监控任务负载。

[使用率钳制（UCLAMP 或 util clamp）](https://docs.kernel.org/scheduler/sched-util-clamp.html)是一种帮助管理任务性能需求的调度器功能。

有关更多信息，请参阅[定制 CPU 调度器](./customize-for-performance-tuning#customize-cpu-scheduler)。

## **了解 CPU 频率调速器**

CPU 频率调速器根据任务负载调整 CPU 频率。CPU 调度器为此过程提供必要的输入。

Qualcomm Linux 使用 Linux 内核提供的 `schedutil` 调速器。

该调速器在系统负载较重时提高 CPU 频率，在负载较低时降低频率，从而确保功耗与性能之间的最佳平衡。

有关更多信息，请参阅以下内容：

* [CPU frequency and voltage scaling code in the Linux kernel](https://www.kernel.org/doc/Documentation/cpu-freq/governors.txt)
* [配置 CPU](./configure-cpu-gpu-and-memory#configure-cpu)
* [定制 CPU 频率调速器](./customize-for-performance-tuning#customize-cpu-frequency-governor)

## **了解 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 调速器](./customize-for-performance-tuning#customize-static-map-dvfs-governor)。

### **了解 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 调速器](./customize-for-performance-tuning#customize-bwmon-governor)

## **了解 Userspace Resource Manager**

Userspace Resource Manager（URM）是一个开源、轻量级且可扩展的框架，旨在从用户空间智能地管理和配置系统资源。

现代工作负载在服务器、计算、XR、移动和物联网等细分领域差异巨大，每种用例都表现出不同的特征。有些工作负载需要高 CPU 频率，有些需要持续的 GPU 吞吐量，还有许多依赖高效的缓存或更大的内存带宽。与此同时，这些工作负载运行在能力、功耗范围和用户期望各不相同的多种硬件平台上。因此，统一的调优方法不足以满足此类环境的多样化性能和功耗需求。

URM 通过提供以下能力来应对这些挑战：

* 启用应用程序级调优
* 启用用例和工作负载级调优
* 提供信号和调优 API

URM 会自动检测用例，并应用在每应用程序或用例 YAML 配置文件中指定的调优参数。用例检测可以通过扩展进行定制。

URM 还可以修改系统行为，以高效管理间歇性工作负载。可以在特定代码段中调用 Signal API 或 Tune API，以临时提升或限制系统资源。例如，可以在定义的持续时间内以更高的 CPU 频率执行关键代码路径。URM 可以高效处理来自多个客户端的并发请求。当多个请求针对同一资源时，URM 会聚合这些请求，以确定并应用设备所需的最佳性能水平。

有关更多信息，请参阅 [Userspace Resource Manager](https://qualcomm.github.io/userspace-resource-manager/) 和 [Userspace Resource Manager Extensions](https://github.com/qualcomm/userspace-resource-manager-extensions/)。

## **了解内存管理**

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

<div className="flex flex-col items-center gap-2">
  <img src="https://mintcdn.com/qualcomm-staging/uWQLnBcS9sxlZhgB/System/Performance/media/k2l-performance/memory_partitioning.svg?fit=max&auto=format&n=uWQLnBcS9sxlZhgB&q=85&s=41c9de093f8cc188f3315f46e0684c9d" alt="图：内存分区" width="600" height="343" data-path="System/Performance/media/k2l-performance/memory_partitioning.svg" />

  <p className="text-sm text-gray-700">
    图：内存分区
  </p>
</div>

该图显示了同时支持 Linux 和非 Linux 环境的系统中的 RAM 分配。

* 系统 RAM 在非 Linux 和 Linux 组件之间进行分区。
* 非 Linux 部分包含一个标记为 Reserved（保留）的大块，表示为非 Linux 操作分配的内存。
* Linux 部分在 Memory total（系统 RAM）下分为四个块：
  * 内核静态
  * 内核动态
  * 用户空间进程
  * 空闲内存

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

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

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

### **配置 RAM 内存分区**

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

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

**表：RAM 分类**

<table style={{ width: '100%', borderCollapse: 'collapse' }}>
  <thead>
    <tr>
      <th style={{ textAlign: 'left' }}>RAM 分类</th>
      <th style={{ textAlign: 'left' }}>内存段</th>
      <th style={{ textAlign: 'left' }}>分配类型</th>
      <th style={{ textAlign: 'left' }}>说明</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>非 Linux</td>
      <td>无</td>
      <td>无</td>
      <td>内存由 Linux 以外的各个子系统以划出区（carveout）形式保留。这些划出区在相应的 DTSI 文件中指定。</td>
    </tr>

    <tr>
      <td rowSpan={14} style={{ verticalAlign: 'top' }}>Linux（系统 RAM）</td>
      <td style={{ verticalAlign: 'top' }}>内核静态</td>
      <td style={{ verticalAlign: 'top' }}>Vmlinux + 内核页结构</td>

      <td>
        内核在引导时为自身使用保留此内存。<strong>Vmlinux</strong> 是用于存储 vmlinux 镜像的内存。vmlinux 镜像的大小和明细可以在引导时从 <code>dmesg</code> 日志中获取。内核页结构内存按<strong>每 GB RAM 大小 16 MB</strong> 计算。
      </td>
    </tr>

    <tr>
      <td rowSpan={8} style={{ verticalAlign: 'top' }}>内核动态</td>
      <td style={{ verticalAlign: 'top' }}>Slab</td>

      <td>
        <ul>
          <li>内核使用 slab 更快、更高效地使用常用数据结构的内存。</li>
          <li>要检查 slab 的内存使用情况，请运行以下命令：</li>
        </ul>

        <pre><code>cat /proc/meminfo | grep -i slab</code></pre>

        <ul>
          <li>要查看各种 slab 及其使用情况的明细，请在内核配置中启用 <code>CONFIG\_SLUB\_DEBUG</code>，然后运行以下命令：</li>
        </ul>

        <pre><code>cat /proc/slabinfo</code></pre>
      </td>
    </tr>

    <tr>
      <td style={{ verticalAlign: 'top' }}>内核栈</td>

      <td>
        内核栈存储每个进程的调用栈。

        <br />

        <br />

        <strong>检查内核栈使用情况：</strong>
        <pre><code>cat /proc/meminfo | grep -i kernelstack</code></pre>
      </td>
    </tr>

    <tr>
      <td style={{ verticalAlign: 'top' }}>PageTables</td>

      <td>
        内核使用内存来存储将虚拟地址映射到物理地址的 PageTables。

        <br />

        <br />

        <strong>检查 PageTables 使用情况：</strong>
        <pre><code>cat /proc/meminfo | grep -i PageTables</code></pre>
      </td>
    </tr>

    <tr>
      <td style={{ verticalAlign: 'top' }}>模块</td>

      <td>
        表示作为内核模块动态加载的内核实体。

        <br />

        <br />

        <strong>列出已加载的内核模块：</strong>
        <pre><code>cat /proc/modules</code></pre>
      </td>
    </tr>

    <tr>
      <td style={{ verticalAlign: 'top' }}>Vmalloc</td>

      <td>
        用于分配连续内存。

        <br />

        <br />

        <strong>检查 Vmalloc 明细：</strong>
        <pre><code>cat /proc/vmallocinfo</code></pre>
      </td>
    </tr>

    <tr>
      <td style={{ verticalAlign: 'top' }}>缓存（内核 + 用户空间）</td>

      <td>
        驻留在 RAM 中的文件支持内存量。

        <br />

        <br />

        <strong>检查缓存内存使用情况：</strong>
        <pre><code>cat /proc/meminfo | grep -i cached</code></pre>
      </td>
    </tr>

    <tr>
      <td style={{ verticalAlign: 'top' }}>缓冲区</td>

      <td>
        包含从磁盘读取或写入磁盘的信息块的固定大小缓冲区。

        <br />

        <br />

        <strong>检查缓冲区内存使用情况：</strong>
        <pre><code>cat /proc/meminfo | grep -i buffers</code></pre>
      </td>
    </tr>

    <tr>
      <td style={{ verticalAlign: 'top' }}>Shmem</td>

      <td>
        映射到两个或多个进程地址空间的共享内存。

        <br />

        <br />

        <strong>检查 shmem 使用情况：</strong>
        <pre><code>cat /proc/meminfo | grep -i shmem</code></pre>
      </td>
    </tr>

    <tr>
      <td rowSpan={5} style={{ verticalAlign: 'top' }}>用户空间</td>
      <td style={{ verticalAlign: 'top' }}>ZUSED（ZRAM）</td>
      <td>经 ZRAM 压缩后的匿名内存。</td>
    </tr>

    <tr>
      <td style={{ verticalAlign: 'top' }}>CMA</td>
      <td>通常映射到视频和显示等硬件 IP 但在运行时分配的连续物理内存。只有可移动分配（例如用户空间进程分配）可以使用 CMA 空闲内存；内核分配不能使用。</td>
    </tr>

    <tr>
      <td style={{ verticalAlign: 'top' }}>ANON</td>

      <td>
        用户空间应用程序使用 <code>malloc()</code> 或 <code>new()</code> 分配的内存。

        <br />

        <br />

        <strong>检查每进程 ANON 使用情况：</strong>
        <pre><code>cat /proc/\<pid>/smaps</code></pre>
      </td>
    </tr>

    <tr>
      <td style={{ verticalAlign: 'top' }}>ION</td>

      <td>
        <ul>
          <li>支持视频、摄像头和 Qualcomm Linux 等硬件 IP 之间的缓冲区共享。ION 管理引导时保留的内存池。</li>
          <li>挂载 debugfs：</li>
        </ul>

        <pre><code>mount -t debugfs none /sys/kernel/debug</code></pre>

        <ul>
          <li>检查 ION 缓冲区使用情况：</li>
        </ul>

        <pre><code>cat /sys/kernel/debug/dma\_buf/bufinfo | grep bytes</code></pre>
      </td>
    </tr>

    <tr>
      <td style={{ verticalAlign: 'top' }}>KGSL</td>

      <td>
        <ul>
          <li>图形驱动程序分配的内存。</li>
          <li>整体 KGSL 使用情况：</li>
        </ul>

        <pre><code>cat /sys/class/kgsl/kgsl/page\_alloc</code></pre>

        <ul>
          <li>进程级明细：</li>
        </ul>

        <pre><code>cat /sys/class/kgsl/kgsl/proc/\<pid>/kernel</code></pre>
      </td>
    </tr>

    <tr>
      <td>空闲内存</td>
      <td>无</td>
      <td>无</td>

      <td>
        可用于任何分配的空闲内存。

        <br />

        <br />

        <strong>检查可用内存：</strong>
        <pre><code>cat /proc/meminfo | grep -i MemFree</code></pre>
      </td>
    </tr>
  </tbody>
</table>

## **了解实时（RT）内核**

实时系统是一种确定性系统，要求在设定的时间内对事件做出响应。

如果满足以下条件，系统即被归类为兼容 RT：

* 不存在无界延迟。
* 最大响应时间可以精确计算。
* 满足设定的任务调度标准（延迟和截止期限）。

Linux 可以配置为实时操作系统（RTOS），其中实时任务具有明确定义的周期性执行周期（周期时间），并在指定限制（抖动）内满足执行标准。

要安装补丁，请参阅 [Versions of PREEMPT\_RT patches](https://wiki.linuxfoundation.org/realtime/start)。

<Note>
  实时支持面向内核空间进程，而非用户空间。
</Note>

<Note>
  本节不适用于 QCS5430。
</Note>

<div className="flex flex-col items-center gap-2">
  <img src="https://mintcdn.com/qualcomm-staging/uWQLnBcS9sxlZhgB/System/Performance/media/k2l-performance/RT-kernel-build-sequence.svg?fit=max&auto=format&n=uWQLnBcS9sxlZhgB&q=85&s=0842a869760350786d35d42e5cd35f7a" alt="图：构建顺序" width="1062" height="161" data-path="System/Performance/media/k2l-performance/RT-kernel-build-sequence.svg" />

  <p className="text-sm text-gray-700">图：构建顺序</p>
</div>

### **设置工作区**

Qualcomm Linux 内核支持 LTS RT 内核（6.18.x），该内核通过 `meta-qcom` 层中 `recipes-kernel/linux/linux-qcom-rt_6.18.bb` 文件的 Yocto 配方进行维护。

有关克隆工作区并获取所有 Qualcomm Linux meta 层以使用 Qualcomm RT Linux 的更多信息，请参阅 [Sync](https://dragonwingdocs.qualcomm.com/Key-Documents/Firmware-Guide/build-firmware)。

### **启用 RT 内核**

Qualcomm Linux `meta-qcom` 层支持 `linux-qcom-rt_6.18.bb` 配方，该配方默认为受支持的机器获取并构建 Qualcomm Linux 内核。

`meta-qcom` 层在现有层之上应用更改。在内核构建期间，`meta-qcom` 层根据内核版本使用 `rt.config` 启用 `PREEMPT_RT`，并允许实时配置。

<Note>
  * 对于 QLI.2.x，使用 `linux-qcom-rt_6.18.bb`。
  * 对于 `qcom-next`，使用 `linux-qcom-next-rt_git.bb`。
</Note>

有关受支持机器的更多信息，请参阅[选择 MACHINE、DISTRO 和镜像](https://dragonwingdocs.qualcomm.com/Key-Documents/Yocto-Guide/build-qualcomm-linux#selecting-machine-distro-and-image)。

### **定制 RT 内核**

* 如果您对 RT 内核有任何更改，请按如下方式在配方中维护它们：
  * 将补丁文件维护在 `recipes-kernel/linux/linux-qcom-6.18/<your_patch_file>.patch` 下
  * 将补丁文件追加到 `recipes-kernel/linux/linux-qcom-rt_6.18.bb` 文件中的 `SRC_URI`。

```text theme={null}
SRC_URI += " \
    file://<your_patch_file>.patch \
    "
```

* 要在 RT 内核上应用任何外部配置：
  * 在 `recipes-kernel/linux/linux-qcom-6.18/configs/<your_config>.cfg` 配方中维护配置文件。
  * 将配置文件追加到 `recipes-kernel/linux/linux-qcom-rt_6.18.bb` 文件中的 `SRC_URI`。

```text theme={null}
SRC_URI += " \
    file://configs/qcom_rt.cfg \
"
```

* 要修改内核命令行，请将命令行参数添加到 `meta-qcom/ci/base.yml` 文件的 `KERNEL_CMDLINE_EXTRA` 变量中。

```text theme={null}
KERNEL_CMDLINE_EXTRA:append = " qcom_scm.download_mode=1 <new_parameter>"
```

### **为 RT 内核配置内核设置**

RT 内核中使用可选和必需的内核配置。

要在 RT 内核中启用完全抢占，请使用 `CONFIG_PREEMPT_RT`。

作为 `linux-qcom-rt_6.18.bb` 配方中使用的 `rt.config` 的一部分，`CONFIG_PREEMPT_RT` 标志默认启用。

以下示例显示了内核配置：

```text theme={null}
zcat proc/config.gz | grep CONFIG_PREEMPT
# CONFIG_PREEMPT_NONE is not set
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
CONFIG_PREEMPT_RT=y
```

在为 RT 任务设置亲和性时，请设置以下内核配置选项：

* `CONFIG_NO_HZ_COMMON` - 启用后，为无滴答（tickless）运行配置内核基础设施。
* `CONFIG_NO_HZ_FULL` - 启用后，配置内核以避免向只有单个可运行任务的 CPU 发送调度时钟中断。
* `CONFIG_CPUSETS` - 使用 `CONFIG_CPUSETS` 配置选项启用 `cpuset`，即将 CPU 分组形成一个集合。

<div className="flex flex-col items-center gap-2">
  <img src="https://mintcdn.com/qualcomm-staging/uWQLnBcS9sxlZhgB/System/Performance/media/k2l-performance/compile-RT-kernel.svg?fit=max&auto=format&n=uWQLnBcS9sxlZhgB&q=85&s=3a8920a31473b1c9f11817cd7bdb212e" alt="图：RT 内核验证" width="1059" height="196" data-path="System/Performance/media/k2l-performance/compile-RT-kernel.svg" />

  <p className="text-sm text-gray-700">图：RT 内核验证</p>
</div>

### **构建 RT 内核**

要构建 RT 内核，请运行以下命令：

1. 要确保您处于 KAS shell 中，请运行以下命令：

```text theme={null}
kas shell meta-qcom/ci/qcs6490-rb3gen2-core-kit.yml:meta-qcom/ci/linux-qcom-rt-6.18.yml:meta-qcom/ci/qcom-distro-kvm.yml:meta-qcom/ci/lock.yml
```

<Note>
  `qcom-distro-kvm.yml` 配置仅在 QLI 2.0 中支持 KVM。RT 内核（`PREEMPT_RT`）与虚拟机监控程序无关。KVM 因以下原因被选为 QLI 2.0 的默认虚拟机监控程序：

  * **上游社区支持** — KVM 及其驱动程序是主线 Linux 内核的一部分，可实现更广泛的生态系统贡献和长期支持。
  * **标准 VirtIO 支持** — KVM 支持所有上游 VirtIO 设备，并与 QEMU 等标准 VMM 兼容。
  * **开放开发** — 活跃的上游社区，开发者熟悉度更高。
</Note>

kas 构建命令会自动将 `xbl_config_kvm.elf` 包含在生成的 `qcomflash` 包中。无需手动进行 UEFI BDS 配置。

<Note>
  将 kas 锁定文件从 meta-qcom-releases 复制到 meta-qcom，请参阅 [Build a BSP image](https://dragonwingdocs.qualcomm.com/Key-Documents/Firmware-Guide/build-firmware#build-bsp-image)。
</Note>

2. 要编译 BitBake Qualcomm Linux 多媒体镜像，请运行以下命令：

```text theme={null}
bitbake qcom-multimedia-image
```

### **调优 RT 内核**

调优 RT 内核，以便为设备中的 RT 任务实现确定性延迟。

将运行 RT 任务的 CPU 核心设置为以最大工作频率运行，同时防止 CPU 频率的热缓解。例如，在空闲休眠场景中，RT 任务会因 CPU 唤醒时间延迟而面临调度延迟。

<Note>
  当启动 RT 测试（cyclictest）时，[URM](./features-impacting-performance#understand-the-userspace-resource-manager) 会自动应用这些优化。

  > 正常运行时**不需要**手动配置。
  > 以下步骤仅供参考、调试或自定义设置使用。

  要在运行测试之前配置系统，请对 QCS6490、Qualcomm Dragonwing<sup>™</sup> IQ-9075 和 Qualcomm Dragonwing<sup>™</sup> IQ-615 Development Kit 执行以下操作：

  1. 禁用定时器迁移：
     ```text theme={null}
     echo 0 > /proc/sys/kernel/timer_migration
     ```
  2. 将 `/sys/devices/virtual/workqueue/*` 中的所有内核工作队列亲和到管家（housekeeping）CPU：
     ```text theme={null}
     for wq in /sys/devices/virtual/workqueue/*; do
        [ -w "$wq/cpumask" ] && echo 7F > "$wq/cpumask"
     done
     # 7F = CPUs 0-6 (binary 0111 1111)
     ```
  3. 将 CPU 频率调速器设置为 performance：
     ```text theme={null}
     for policy in /sys/devices/system/cpu/cpufreq/policy*; do
        [ -w "$policy/scaling_governor" ] && echo performance > "$policy/scaling_governor"
     done
     ```
  4. 禁用 RT 记账/节流：
     ```text theme={null}
     echo -1 > /proc/sys/kernel/sched_rt_runtime_us
     ```
  5. 将 IRQ 亲和性设置为管家 CPU：
     ```text theme={null}
     ALLOW_CPUS="0,1,2,3,4,5,6"
     cpu_list_to_mask() {
        MASK=0
        for cpu in $(echo $1 | tr ',' ' '); do
           MASK=$((MASK | (1 << cpu)))
        done
        printf "%x\n" "$MASK"
     }
     MASK=$(cpu_list_to_mask "$ALLOW_CPUS")
     echo "Setting IRQ affinity to CPUs: $ALLOW_CPUS (mask=0x$MASK)"
     for irq in /proc/irq/[0-9]*; do
        smp_file="$irq/smp_affinity"
        [ -w "$smp_file" ] && echo "$MASK" > "$smp_file" 2>/dev/null
     done
     ```

  要在运行测试之前配置系统，请对 Dragonwing<sup>™</sup> IQ-8275 Development Kit 执行以下操作：

  1. 禁用定时器迁移：
     ```text theme={null}
     echo 0 > /proc/sys/kernel/timer_migration
     ```
  2. 将 `/sys/devices/virtual/workqueue/*` 中的所有内核工作队列亲和到管家 CPU：
     ```text theme={null}
     for wq in /sys/devices/virtual/workqueue/*; do
        [ -w "$wq/cpumask" ] && echo F7 > "$wq/cpumask"
     done
     # F7 = CPUs 0–2,4-7 (binary 1111 0111)
     ```
  3. 将 CPU 频率调速器设置为 performance：
     ```text theme={null}
     for policy in /sys/devices/system/cpu/cpufreq/policy*; do
        [ -w "$policy/scaling_governor" ] && echo performance > "$policy/scaling_governor"
     done
     ```
  4. 禁用 RT 记账/节流：
     ```text theme={null}
     echo -1 > /proc/sys/kernel/sched_rt_runtime_us
     ```
  5. 将 IRQ 亲和性设置为管家 CPU：
     ```text theme={null}
     ALLOW_CPUS="0,1,2,4,5,6,7"
     cpu_list_to_mask() {
        MASK=0
        for cpu in $(echo $1 | tr ',' ' '); do
           MASK=$((MASK | (1 << cpu)))
        done
        printf "%x\n" "$MASK"
     }
     MASK=$(cpu_list_to_mask "$ALLOW_CPUS")
     echo "Setting IRQ affinity to CPUs: $ALLOW_CPUS (mask=0x$MASK)"
     for irq in /proc/irq/[0-9]*; do
        smp_file="$irq/smp_affinity"
        [ -w "$smp_file" ] && echo "$MASK" > "$smp_file" 2>/dev/null
     done
     ```

  以下示例显示了如何在 `meta-qcom/conf/machine/<machine-name.conf>` 中添加内核命令行参数以禁用 RCU 回调（**rcu\_nocbs**）：

  * CPU 核心 7
  * IRQ 亲和到核心 0-6
  * RCU 无回调 7

  ```text theme={null}
  QCOM_RT_CPU        = "7"
  QCOM_IRQAFF        = "0-6"
  QCOM_RCU_NOCBS     = "7"
  QCOM_RCU_EXPEDITED = "1"
  QCOM_CPUIDLE_OFF   = "1"
  ```
</Note>

### **测试 RT 内核**

Linux 基金会 RT 测试套件中提供了一组测试。RT Linux 内核测试可获取以下信息：

* RT Linux 内核的实时性能
* RT Linux 内核延迟和关键性能指标（KPI）

<Note>
  RT Linux 内核测试运行时间超过 24 小时，在此期间请勿重启系统。
</Note>

Cyclictest 工具用于对 RT Linux 内核系统进行基准测试。它用于评估实时系统的相对性能。Qualcomm Linux 构建中包含 cyclictest 工具。有关更多信息，请参阅 [Cyclictest](https://wiki.linuxfoundation.org/realtime/documentation/howto/tools/cyclictest/start)。

本指南介绍以下 cyclictest：

* 无负载 cyclictest：执行此测试时不添加系统负载。
* 使用 stress-ng（下一代）的 cyclictest：执行此测试时添加特定百分比的负载，以测量最坏情况下的系统延迟。

1. 对 QCS6490、Qualcomm Dragonwing<sup>™</sup> IQ-9075 和 Qualcomm Dragonwing<sup>™</sup> IQ-615 开发套件运行以下循环测试：
   ```text theme={null}
   cyclictest -a 7 -t 1 -m -l 100000000 -i 1000 -p 99 -h 100
   # -a 7 → pin threads to CPU 7 (RT cores)
   # -t 1 → 1 threads
   # -m → lock memory (avoid page faults)
   # -l 100000000 → long run
   # -i 1000 → 1 ms interval
   # -p 99 → RT priority
   # -h 100 → histogram up to 100 µs
   ```
2. 对 Dragonwing<sup>™</sup> IQ-8275 Development Kit 运行以下循环测试：
   ```text theme={null}
   cyclictest -a 3 -t 1 -m -l 100000000 -i 1000 -p 99 -h 100
   ```

要访问 RT 测试套件源代码，请参阅 [rt-tests/rt-tests.git](https://git.kernel.org/pub/scm/utils/rt-tests/rt-tests.git/)。有关更多信息，请参阅 [RT-Tests](https://wiki.linuxfoundation.org/realtime/documentation/howto/tools/rt-tests)。

3. 记录延迟。

要在 QCS6490、Qualcomm Dragonwing IQ-9075 和 Qualcomm Dragonwing<sup>™</sup> IQ-615 上使用 stress-ng 运行循环测试，请执行以下操作：

1. 设置目标 CPU 负载。定义所需的 CPU 负载百分比。如果未指定，默认负载为 60%：
   ```text theme={null}
   LOAD=60
   ```
2. 在后台在选定的 CPU 核心上运行 stress-ng。使用 stress-ng 对核心 0、1、2、4、5、6 和 7 施加 CPU 负载。每个实例运行一天并固定到特定的 CPU 核心：
   ```text theme={null}
   for cpu in 0 1 2 3 4 5 6; do
       taskset -c $cpu stress-ng --cpu 1 --cpu-load "$LOAD" \
       --temp-path . -t 1d &
   done
   ```
3. 运行循环延迟测试。以高优先级执行 cyclictest 以测量调度延迟。该测试运行约 27.78 小时：
   ```text theme={null}
   cyclictest -a 7 -t 1 -m -l 100000000 -i 1000 -p 99 -h 100 --mainaffinity 6
   ```
4. 记录最坏情况的延迟。

要在 Dragonwing IQ-8275 上使用 stress-ng 运行循环测试，请执行以下操作：

1. 设置目标 CPU 负载：
   ```text theme={null}
   LOAD=60
   ```
2. 在选定的 CPU 核心上运行 stress-ng：
   ```text theme={null}
   for cpu in 0 1 2 4 5 6 7; do
        taskset -c $cpu stress-ng --cpu 1 --cpu-load "$LOAD" \
        --temp-path . -t 1d &
   done
   ```
3. 运行循环延迟测试：
   ```text theme={null}
   cyclictest -a 3 -t 1 -m -l 100000000 -i 1000 -p 99 -h 100 --mainaffinity 2
   ```
4. 记录最坏情况的延迟。

### **RT 测试结果**

<table style={{ width: '100%', borderCollapse: 'collapse' }}>
  <thead>
    <tr>
      <th style={{ textAlign: 'center' }}>设备</th>
      <th style={{ textAlign: 'center' }}>发行版和镜像</th>
      <th style={{ textAlign: 'center' }}><span style={{ whiteSpace: 'nowrap' }}>循环测试用例</span> <br />（持续时间：24 小时）</th>
      <th style={{ textAlign: 'center' }}>最小延迟（µs）</th>
      <th style={{ textAlign: 'center' }}>平均延迟（µs）</th>
      <th style={{ textAlign: 'center' }}>最大延迟（µs）</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td rowSpan={2} style={{ textAlign: 'center', verticalAlign: 'middle' }}>
        QCS6490<br />
        RT 核心：7<br />
        引导流程 - KVM
      </td>

      <td rowSpan={2} style={{ textAlign: 'center', verticalAlign: 'middle' }}>
        performance\_linux-qcom-rt-6.18\_qcom-distro-kvm<br />
        和 qcom-multimedia-image
      </td>

      <td style={{ textAlign: 'center' }}>无负载</td>
      <td style={{ textAlign: 'center' }}>1</td>
      <td style={{ textAlign: 'center' }}>1</td>
      <td style={{ textAlign: 'center' }}>6</td>
    </tr>

    <tr>
      <td style={{ textAlign: 'center' }}>Stress-NG</td>
      <td style={{ textAlign: 'center' }}>1</td>
      <td style={{ textAlign: 'center' }}>1</td>
      <td style={{ textAlign: 'center' }}>6</td>
    </tr>

    <tr>
      <td rowSpan={2} style={{ textAlign: 'center', verticalAlign: 'middle' }}>
        <span style={{ whiteSpace: 'nowrap' }}>Dragonwing IQ-615</span><br />
        RT 核心：7<br />
        引导流程 - KVM
      </td>

      <td rowSpan={2} style={{ textAlign: 'center', verticalAlign: 'middle' }}>
        performance\_linux-qcom-rt-6.18\_qcom-distro-kvm<br />
        和 qcom-multimedia-image
      </td>

      <td style={{ textAlign: 'center' }}>无负载</td>
      <td style={{ textAlign: 'center' }}>1</td>
      <td style={{ textAlign: 'center' }}>2</td>
      <td style={{ textAlign: 'center' }}>7</td>
    </tr>

    <tr>
      <td style={{ textAlign: 'center' }}>Stress-NG</td>
      <td style={{ textAlign: 'center' }}>1</td>
      <td style={{ textAlign: 'center' }}>2</td>
      <td style={{ textAlign: 'center' }}>9</td>
    </tr>

    <tr>
      <td rowSpan={2} style={{ textAlign: 'center', verticalAlign: 'middle' }}>
        <span style={{ whiteSpace: 'nowrap' }}>Dragonwing IQ-9075</span><br />
        RT 核心：7<br />
        引导流程 - KVM
      </td>

      <td rowSpan={2} style={{ textAlign: 'center', verticalAlign: 'middle' }}>
        performance\_linux-qcom-rt-6.18\_qcom-distro-kvm<br />
        和 qcom-multimedia-image
      </td>

      <td style={{ textAlign: 'center' }}>无负载</td>
      <td style={{ textAlign: 'center' }}>1</td>
      <td style={{ textAlign: 'center' }}>2</td>
      <td style={{ textAlign: 'center' }}>5</td>
    </tr>

    <tr>
      <td style={{ textAlign: 'center' }}>Stress-NG</td>
      <td style={{ textAlign: 'center' }}>1</td>
      <td style={{ textAlign: 'center' }}>2</td>
      <td style={{ textAlign: 'center' }}>5</td>
    </tr>

    <tr>
      <td rowSpan={2} style={{ textAlign: 'center', verticalAlign: 'middle' }}>
        <span style={{ whiteSpace: 'nowrap' }}>Dragonwing IQ-8275</span><br />
        RT 核心：3<br />
        引导流程 - KVM
      </td>

      <td rowSpan={2} style={{ textAlign: 'center', verticalAlign: 'middle' }}>
        performance\_linux-qcom-rt-6.18\_qcom-distro-kvm<br />
        和 qcom-multimedia-image
      </td>

      <td style={{ textAlign: 'center' }}>无负载</td>
      <td style={{ textAlign: 'center' }}>1</td>
      <td style={{ textAlign: 'center' }}>2</td>
      <td style={{ textAlign: 'center' }}>7</td>
    </tr>

    <tr>
      <td style={{ textAlign: 'center' }}>Stress-NG</td>
      <td style={{ textAlign: 'center' }}>1</td>
      <td style={{ textAlign: 'center' }}>2</td>
      <td style={{ textAlign: 'center' }}>6</td>
    </tr>
  </tbody>
</table>

## **后续步骤**

* [针对性能调优进行定制](./customize-for-performance-tuning)
* [使用工具分析性能](./analyze-performance-with-tools)
