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

# libqcperf

> 一个用于在 Qualcomm 芯片组上进行实时性能监控的轻量级 C 库，提供面向 CPU、NPU 以及功耗/热指标的可插拔后端。

libqcperf 是一个开源 C 库，用于在 Qualcomm 平台上进行实时硬件性能监控。它提供统一的 API，将调用分发到可插拔的后端，每个后端针对特定的硬件子系统。数据在后台线程上异步采集，并以可配置的流式速率通过注册的回调传递给您的应用程序。

源代码和问题跟踪器：[github.com/qualcomm/libqcperf](https://github.com/qualcomm/libqcperf)

## 后端

每个后端针对特定的子系统和平台。您可以在构建时选择要编译进来的后端。

| 后端        | 平台            | 关键指标                                               |
| --------- | ------------- | -------------------------------------------------- |
| `DUMMY`   | 全部            | 跨两种能力的合成指标——适合在没有硬件的情况下进行集成测试                      |
| `CPU`     | Linux ARM64   | 每核及总体 CPU 负载（%）、频率（MHz）、有效利用率（%）、DCVS 频率限制         |
| `NPU`     | Linux ARM64   | DSP/NPU Q6 利用率（%）、Q6 时钟（KHz）、HVX 利用率（%）、HMX 利用率（%） |
| `POWER`   | Windows ARM64 | CPU、GPU 和系统组件的功耗（mW）                               |
| `THERMAL` | Windows ARM64 | 22 个热区（包括 CPU 集群和 GPU）的温度（°C）                      |

## 构建

### Linux ARM64（交叉编译）

<Steps>
  <Step title="安装前提条件">
    为您的主机下载 ARM GNU Toolchain 并设置路径：

    ```bash theme={null}
    export AARCH64_TOOLCHAIN_PATH=/path/to/arm-gnu-toolchain
    ```
  </Step>

  <Step title="使用 CMake 配置">
    ```bash theme={null}
    cmake -S qcperf -B build \
        -DTARGET_ARCH=linux-aarch64 \
        -DCMAKE_BUILD_TYPE=Release \
        -DProjectVersion="0.1.0.0" \
        -DBACKENDS="CPU;NPU;DUMMY" \
        -DBUILD_SHARED=OFF
    ```

    关键标志：

    | 标志                   | 取值                  | 描述                            |
    | -------------------- | ------------------- | ----------------------------- |
    | `-DTARGET_ARCH`      | `linux-aarch64`     | 选择交叉编译工具链                     |
    | `-DCMAKE_BUILD_TYPE` | `Release` / `Debug` | 优化构建或带调试符号                    |
    | `-DProjectVersion`   | `"0.1.0.0"`         | 嵌入库中的版本字符串                    |
    | `-DBACKENDS`         | `"CPU;NPU;DUMMY"`   | 以分号分隔的要编译的后端列表；省略则启用平台支持的所有后端 |
    | `-DBUILD_SHARED`     | `OFF` / `ON`        | 静态 `.a` 或共享 `.so`             |
  </Step>

  <Step title="构建">
    ```bash theme={null}
    cmake --build build
    ```

    输出位于构建目录根部：`libQcPerfCore.a`（静态）或 `libQcPerfCore.so`（共享），以及 `QcPerfCoreTest` 可执行文件。
  </Step>
</Steps>

### CMake 预设

编辑 `qcperf/CMakeUserPresets.json`，一次性设置 `AARCH64_TOOLCHAIN_PATH` 和 `ProjectVersion`，然后使用命名预设：

```bash theme={null}
cd qcperf
cmake --preset linux-aarch64-release
cmake --build --preset linux-aarch64-release
```

可用预设：`linux-aarch64-debug`、`linux-aarch64-release`、`linux-aarch64-debug-shared`、`linux-aarch64-release-shared`。

### Windows ARM64

```bash theme={null}
git submodule update --init --recursive
cmake -B build -G "Visual Studio 17 2022" -A ARM64 -DProjectVersion="0.1.0.0"
cmake --build build --config Release
```

## API 概览

所有函数都返回 `QcPerfReturnCode`。请包含 `qcperf.h` 和 `qcperf_common.h`。

| 函数                                       | 描述                              |
| ---------------------------------------- | ------------------------------- |
| `qcperf_init()`                          | 初始化库。必须首先调用。                    |
| `qcperf_version(info)`                   | 获取库版本（build.major.minor.patch）。 |
| `qcperf_connect_backend(id, msg_cb)`     | 连接到后端，并可选地注册消息回调。               |
| `qcperf_get_capabilities_info(id, info)` | 查询已连接后端的能力、指标和支持的速率。            |
| `qcperf_set_data_callback(id, data_cb)`  | 注册在每个流式传输间隔被调用的数据回调。            |
| `qcperf_start(id, request)`              | 以给定的采样和流式传输速率开始监控某项能力。          |
| `qcperf_stop(id, request)`               | 停止活动的监控会话。                      |
| `qcperf_disconnect_backend(id)`          | 断开与后端的连接并释放其资源。                 |
| `qcperf_deinit()`                        | 反初始化库并释放所有资源。                   |
| `qcperf_get_error_info(code, info)`      | 将返回码转换为人类可读的字符串。                |

## 测试应用程序

构建会生成 `QcPerfCoreTest`，这是一个演练完整库生命周期的单文件 C 程序。它是标准的用法示例。

### 运行测试应用程序

```bash theme={null}
./QcPerfCoreTest <backend_id> <sampling_rate_ms> <streaming_rate_ms> <verbose_mode>
```

| 参数                  | 描述                                                       |
| ------------------- | -------------------------------------------------------- |
| `backend_id`        | 整数后端标识符（0 = DUMMY，1 = CPU，2 = NPU，3 = POWER，4 = THERMAL） |
| `sampling_rate_ms`  | 硬件采样间隔（毫秒）；传入 `0` 使用后端支持的第一个速率                           |
| `streaming_rate_ms` | 回调传递间隔（毫秒）；传入 `0` 使用后端支持的第一个速率                           |
| `verbose_mode`      | `0` = 仅打印指标 ID 和值；任何其他值 = 同时打印指标名称、单位和描述                 |

**示例：**

```bash theme={null}
# Dummy backend, verbose output, 100 ms sampling, 500 ms streaming
./QcPerfCoreTest 0 100 500 1

# CPU backend, basic output, backend default rates
./QcPerfCoreTest 1 0 0 0
```

### 生命周期

测试应用程序演练完整的 API 调用序列：

<Steps>
  <Step title="初始化">
    ```c theme={null}
    qcperf_init();
    ```
  </Step>

  <Step title="连接到后端">
    ```c theme={null}
    qcperf_connect_backend(backend_id, &message_callback);
    ```
  </Step>

  <Step title="发现能力">
    ```c theme={null}
    qcperf_get_capabilities_info(backend_id, backend_info);
    ```
  </Step>

  <Step title="注册数据回调">
    ```c theme={null}
    qcperf_set_data_callback(backend_id, &result_callback);
    ```
  </Step>

  <Step title="启动、采集、停止——对每项能力执行">
    ```c theme={null}
    qcperf_start(backend_id, &request);
    sleep(10);
    qcperf_stop(backend_id, &request);
    ```
  </Step>

  <Step title="断开连接并反初始化">
    ```c theme={null}
    qcperf_disconnect_backend(backend_id);
    qcperf_deinit();
    ```
  </Step>
</Steps>

### 回调实现

消息回调接收后端日志消息，并带上严重级别前缀打印，同时抑制调试级别的输出：

```c theme={null}
enum QcPerfReturnCode message_callback(struct QcPerfMessage *message) {
    if (message->message_level != QC_PERF_MESSAGE_LEVEL_DEBUG) {
        printf("[%s] Backend message: %s\n", level_str, message->message);
    }
    return QC_PERF_RETURN_CODE_SUCCESS;
}
```

数据回调在每个流式传输间隔被调用。在详细模式下，它从预先复制的 `QcPerfBackendInfo` 中查找指标名称、单位和描述；在基本模式下，它打印指标 ID 和原始值：

```c theme={null}
enum QcPerfReturnCode result_callback(struct QcPerfData *data) {
    printf("[DATA] Capability ID: %d, Metrics count: %d\n",
           data->capabilityId, data->metric_response_len);

    for (uint32_t i = 0; i < data->metric_response_len; i++) {
        if (g_is_verbose_print && metric_found) {
            // verbose: name, value, unit, description
            printf("  [%llu] %s: ", timestamp, metric_name);
            print_metric_value(&data->metric_response[i].metric_value);
            printf(" %s (%s)\n", metric_unit, metric_desc);
        } else {
            // basic: metric ID and value only
            printf("  [%llu] Metric ID %d: ", timestamp,
                   data->metric_response[i].metric_id);
            print_metric_value(&data->metric_response[i].metric_value);
            printf("\n");
        }
    }
    return QC_PERF_RETURN_CODE_SUCCESS;
}
```

<Note>
  数据回调运行在库的内部后台线程上。测试应用程序在启动任何监控会话之前会深拷贝 `QcPerfBackendInfo`，以便回调在无需持有锁的情况下安全读取指标元数据。
</Note>

## 资源

* [GitHub 上的源代码](https://github.com/qualcomm/libqcperf)
