RK3576 Linux CPU/GPU/NPU 性能调优指南
目标平台: RK3576 | NPU 算力: 6 TOPS | 文档版本: V1.0
适用板型: C-3576BQ 核心板 + M4-R2 底板
最后更新: 2026-10-23
1 概述
1.1 文档目的
本文档提供 RK3576 平台在 Linux 6.1 内核下的 CPU、GPU、NPU 性能调优完整指南。涵盖调频策略配置、任务调度优化、功耗管理、性能监控和基准测试等内容,帮助开发者在性能、功耗和散热之间取得最佳平衡。
1.2 RK3576 处理器架构
┌─────────────────────────────────────────────────────────────┐
│ RK3576 SoC │
│ │
│ ┌─────────────────────────┐ ┌─────────────────────────┐ │
│ │ Cortex-A72 Cluster │ │ Cortex-A53 Cluster │ │
│ │ (Big Core) │ │ (Little Core) │ │
│ │ │ │ │ │
│ │ CPU0-3: 最高 2.2 GHz │ │ CPU4-7: 最高 1.8 GHz │ │
│ │ (具体频率以 SDK 为准) │ │ (具体频率以 SDK 为准) │ │
│ └─────────────────────────┘ └─────────────────────────┘ │
│ │
│ ┌─────────────────────┐ ┌───────────────────────────────┐│
│ │ Mali-G52 MC3 GPU │ │ NPU (6 TOPS) ││
│ │ (频率以 SDK 为准) │ │ npu@<base_addr> ││
│ └─────────────────────┘ └───────────────────────────────┘│
└─────────────────────────────────────────────────────────────┘RK3576 CPU/GPU/NPU 的具体运行频率档位与设备树节点地址以实际发布的 RK3576 SDK 为准(待板上确认)。
1.3 调优目标分类
| 调优目标 | 典型场景 | 优先策略 |
|---|---|---|
| 最大性能 | AI推理、视频编码、3D渲染 | performance governor, 最高频率 |
| 均衡模式 | 桌面交互、多媒体播放 | schedutil governor, 动态调频 |
| 最低功耗 | 待机、传感器采集 | powersave governor, 最低频率 |
| 实时响应 | 工业控制、音频处理 | RT调度, CPU绑定, 中断亲和性 |
2 硬件准备
2.1 硬件平台信息
| 组件 | 规格 | 说明 |
|---|---|---|
| 核心板 | C-3576BQ V10 | 8nm工艺, 集成RK3576 |
| 底板 | ShimetaPi M4-R2 V10 | 扩展接口底板 |
| CPU | 4×A72 + 4×A53 | big.LITTLE架构 |
| GPU | Mali-G52 MC3 | 支持 OpenGL ES/OpenCL/Vulkan |
| NPU | 6 TOPS | 支持 INT8/INT16/FP16(具体支持格式以 SDK 为准) |
| 内存 | LPDDR5 4GB | 标配 |
| 存储 | eMMC 32GB | 标配 |
2.2 散热方案建议
性能调优的前提是有效的散热。RK3576 在大负载运行时的实际功耗与散热需求需根据具体场景实测(待板上验证)。M4-R2 底板未配置主动散热风扇接口时,建议根据负载情况自行加装散热片。
散热方案参考:
├── 轻负载: 被动散热片 (铝制, 尽量增大散热面积)
├── 中负载: 散热片 + 低速风扇
└── 重负载: 散热片 + 高速风扇 + 导热硅脂具体散热方案需结合机箱结构和实测温度调整(待板上验证)。
2.3 电源要求
推荐供电:
- 5V/2A(Type-C 或 6pin)电源适配器
- 空载最小电流 1000mA,建议使用足额 5V/2A 电源
- 供电不足会导致系统不稳定和意外降频3 软件准备
3.1 系统环境
# 确认内核版本
uname -r
# 预期输出: 6.1.x-rockchip
# 确认系统信息
cat /etc/os-release
# 确认CPU信息
lscpu | head -203.2 必要软件包安装
# 更新系统
sudo apt update && sudo apt upgrade -y
# 安装性能工具
sudo apt install -y \
linux-tools-common \
linux-tools-$(uname -r) \
sysstat \
htop \
iotop \
cpufrequtils \
libhwloc-dev \
python3-pip \
glmark2 \
glmark2-wayland
# 安装编译工具
sudo apt install -y \
build-essential \
cmake \
pkg-config \
libdrm-devNPU 相关工具链(rknn-toolkit2、rknpu2 等)的安装方式以实际发布的 RK3576 SDK 文档为准。
3.3 验证硬件节点
# 检查CPU频率节点
ls /sys/devices/system/cpu/cpu0/cpufreq/
# 应存在: scaling_governor, scaling_max_freq, scaling_cur_freq 等
# 检查GPU频率节点(节点名以实际 SDK 为准,如 <base_addr>.gpu)
ls /sys/class/devfreq/*.gpu/
# 应存在: governor, cur_freq, max_freq, min_freq
# 检查NPU设备(节点名以实际 SDK 为准)
ls /sys/class/devfreq/npu*/
# 应存在: governor, cur_freq, max_freq
# 检查thermal区域
ls /sys/class/thermal/thermal_zone*/
# RK3576 通常有多个 thermal zone (CPU, GPU, NPU 等)4 操作步骤
4.1 CPU 调频策略配置
4.1.1 查看当前CPU状态
# 查看当前调频策略
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
# 输出: schedutil (默认) 或其他
# 查看当前频率
cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq
# A72 核心 (cpu0-3) 与 A53 核心 (cpu4-7) 频率不同
# 查看可用频率范围(以实际 SDK 为准)
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies
cat /sys/devices/system/cpu/cpu4/cpufreq/scaling_available_frequencies
# 查看可用调频策略
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors
# 输出: performance powersave schedutil 等4.1.2 设置CPU调频策略
# 方法一: 临时设置 (重启失效)
# 全部核心设置为performance
for cpu in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do
echo performance | sudo tee $cpu
done
# 全部核心设置为schedutil (推荐)
for cpu in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do
echo schedutil | sudo tee $cpu
done
# 方法二: 使用cpufreq-set工具
sudo cpufreq-set -g performance
# 或指定核心
sudo cpufreq-set -c 0-3 -g performance # A72 集群
sudo cpufreq-set -c 4-7 -g powersave # A53 集群4.1.3 schedutil 参数调优
# schedutil参数说明
# rate_limit_us: 调频决策最小间隔(微秒)
# 查看schedutil参数
cat /sys/devices/system/cpu/cpufreq/policy0/schedutil/rate_limit_us
# 调整rate_limit_us (降低以提高响应速度)
echo 500 | sudo tee /sys/devices/system/cpu/cpufreq/policy0/schedutil/rate_limit_us
# A72 集群 (policy0) 和 A53 集群 (policy4) 分别配置
echo 500 | sudo tee /sys/devices/system/cpu/cpufreq/policy0/schedutil/rate_limit_us
echo 1000 | sudo tee /sys/devices/system/cpu/cpufreq/policy4/schedutil/rate_limit_us
# 具体 policy 编号以实际 SDK 的 CPU 拓扑为准4.2 GPU 频率调节
4.2.1 查看GPU状态
# GPU设备路径(节点名以实际 SDK 为准)
GPU_PATH=$(ls -d /sys/class/devfreq/*.gpu | head -1)
# 查看GPU当前频率
cat ${GPU_PATH}/cur_freq
# 单位: Hz
# 查看GPU可用频率
cat ${GPU_PATH}/available_frequencies
# 查看GPU调频策略
cat ${GPU_PATH}/governor
# 查看GPU负载
cat ${GPU_PATH}/trans_stat4.2.2 GPU性能模式设置
# 设置GPU为性能模式 (锁定最高频率)
echo performance | sudo tee ${GPU_PATH}/governor
# 手动锁定GPU频率到最高
MAX_FREQ=$(cat ${GPU_PATH}/available_frequencies | awk '{print $NF}')
echo ${MAX_FREQ} | sudo tee ${GPU_PATH}/min_freq
echo ${MAX_FREQ} | sudo tee ${GPU_PATH}/max_freq
# 设置GPU为动态调频模式
echo simple_ondemand | sudo tee ${GPU_PATH}/governor
# 恢复GPU默认频率范围(具体值以实际 SDK 为准)
# echo <min> | sudo tee ${GPU_PATH}/min_freq
# echo <max> | sudo tee ${GPU_PATH}/max_freqRK3576 Mali-G52 MC3 GPU 的频率档位与功耗以实际发布的 RK3576 SDK 为准(待板上验证)。
4.3 NPU 配置
4.3.1 查看NPU状态
# NPU设备路径(节点名以实际 SDK 为准,如 /sys/class/devfreq/npu@<base_addr>)
NPU_PATH=$(ls -d /sys/class/devfreq/npu* | head -1)
# 查看NPU当前频率
cat ${NPU_PATH}/cur_freq
# 查看NPU可用频率
cat ${NPU_PATH}/available_frequencies
# 查看NPU调频策略
cat ${NPU_PATH}/governor4.3.2 NPU性能模式
# NPU设置为性能模式
echo performance | sudo tee ${NPU_PATH}/governor
# 手动锁定NPU最高频率
MAX_FREQ=$(cat ${NPU_PATH}/available_frequencies | awk '{print $NF}')
echo ${MAX_FREQ} | sudo tee ${NPU_PATH}/min_freq
echo ${MAX_FREQ} | sudo tee ${NPU_PATH}/max_freq
# NPU设置为动态调频
echo simple_ondemand | sudo tee ${NPU_PATH}/governor4.3.3 NPU核心选择
# RK3576 NPU 计算核心数量以实际发布的 SDK 为准(待板上确认)
# 通过 rknpu2 库可以指定使用的核心,在 RKNN 模型推理时通过 API 选择:
# - RKNN_NPU_CORE_AUTO: 自动分配
# - RKNN_NPU_CORE_0: 仅核心 0
# - RKNN_NPU_CORE_1: 仅核心 1
# - RKNN_NPU_CORE_0_1: 使用核心 0 和 1
# 具体枚举值以 rknpu2 头文件(rknn_api.h)为准
# 查看NPU设备信息
dmesg | grep -i npu | head -104.4 CPU 亲和性与任务调度
4.4.1 CPU亲和性设置
# 查看进程CPU亲和性
taskset -p <PID>
# 将进程绑定到 A72 大核 (CPU0-3)
taskset -c 0-3 ./my_application
# 将进程绑定到 A53 小核 (CPU4-7)
taskset -c 4-7 ./background_task
# 使用numactl (如可用)
numactl --cpunodebind=0 --membind=0 ./my_application
# 查看CPU拓扑
lscpu -e
# 或
cat /sys/devices/system/cpu/cpu*/topology/physical_package_id4.4.2 big.LITTLE 调度策略
# 查看EAS (Energy Aware Scheduling) 状态
cat /proc/sys/kernel/sched_energy_aware
# 1 = 启用, 0 = 禁用
# 查看CPU容量值 (A72 > A53)
cat /sys/devices/system/cpu/cpu0/cpu_capacity
cat /sys/devices/system/cpu/cpu4/cpu_capacity
# 查看调度器域
ls /proc/sys/kernel/sched_domain/cpu0/4.4.3 实时调度配置
# 设置进程为SCHED_FIFO实时调度 (需要root)
sudo chrt -f 50 ./my_realtime_app
# 设置进程为SCHED_DEADLINE (最高优先级实时)
sudo chrt -d --sched-runtime 5000000 \
--sched-deadline 10000000 \
--sched-period 10000000 \
0 ./my_critical_app
# 设置进程优先级
sudo chrt -f -p 99 <PID>
# 查看当前实时进程
chrt -p
ps -eo pid,cls,rtprio,ni,comm | grep -E "FF|RR|DL"
# 降低非关键进程优先级
sudo renice +10 -p <PID>4.5 散热与温控配置
4.5.1 查看温度信息
# 查看所有thermal zone温度
for tz in /sys/class/thermal/thermal_zone*/; do
zone=$(cat ${tz}/type)
temp=$(cat ${tz}/temp)
echo "${zone}: $((temp/1000))°C"
done
# 常见thermal zone
# cpu-thermal: CPU温度
# gpu-thermal: GPU温度
# npu-thermal: NPU温度
# soc-thermal: SoC整体温度4.5.2 温控策略配置
# 查看温控触发点
cat /sys/class/thermal/thermal_zone0/trip_point_0_temp
cat /sys/class/thermal/thermal_zone0/trip_point_0_type
# type: passive (降频) / active (开风扇) / critical (关机)
# 修改被动降频触发温度 (单位: 毫摄氏度)
# 例如: 设置CPU在85°C开始降频
echo 85000 | sudo tee /sys/class/thermal/thermal_zone0/trip_point_0_temp
# 查看当前冷却设备状态
cat /sys/class/thermal/cooling_device*/type
cat /sys/class/thermal/cooling_device*/cur_state
# 查看是否支持风扇控制
ls /sys/class/thermal/cooling_device*/fan_speed4.5.3 温控优化建议
推荐温控阈值(参考值,可按产品需求调整):
├── 降频触发 (passive): 85°C
├── 风扇全速 (active): 90°C
└── 关机保护 (critical): 105°C
大负载运行时监控脚本:
watch -n 2 "cat /sys/class/thermal/thermal_zone*/temp | \
awk '{printf \"%.1f°C \", \$1/1000}'"实际温控阈值以板载 thermal 驱动配置为准,修改前请确认目标产品的工作温度范围。
4.6 DVFS (动态电压频率调节) 配置
4.6.1 DVFS参数查看
# 查看CPU DVFS表
cat /sys/devices/system/cpu/cpufreq/policy0/scaling_available_frequencies
cat /sys/devices/system/cpu/cpufreq/policy0/scaling_available_governors
# 查看当前频率
cat /sys/devices/system/cpu/cpufreq/policy0/scaling_cur_freq
# GPU DVFS
GPU_PATH=$(ls -d /sys/class/devfreq/*.gpu | head -1)
cat ${GPU_PATH}/available_frequencies
cat ${GPU_PATH}/available_transitions4.6.2 DVFS锁定频率
# 锁定CPU到最高频率(具体频率档位以实际 SDK 为准)
MAX_FREQ=$(cat /sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq)
echo ${MAX_FREQ} | sudo tee /sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq
echo ${MAX_FREQ} | sudo tee /sys/devices/system/cpu/cpufreq/policy0/scaling_min_freq
# 锁定CPU到特定频率(以实际支持的频率档位为准)
# echo <freq> | sudo tee /sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq
# echo <freq> | sudo tee /sys/devices/system/cpu/cpufreq/policy0/scaling_min_freq
# 恢复默认频率范围
MIN_FREQ=$(cat /sys/devices/system/cpu/cpufreq/policy0/scaling_min_freq)
echo ${MIN_FREQ} | sudo tee /sys/devices/system/cpu/cpufreq/policy0/scaling_min_freq
echo ${MAX_FREQ} | sudo tee /sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq4.7 一键性能配置脚本
#!/bin/bash
# rk3576_performance_setup.sh
# RK3576 一键性能模式配置脚本
set -e
echo "=== RK3576 性能模式配置 ==="
# 检查root权限
if [ "$EUID" -ne 0 ]; then
echo "请使用sudo运行此脚本"
exit 1
fi
# 1. CPU设置为performance模式
echo "[1/5] 配置CPU调频策略..."
for gov in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do
echo performance > $gov
done
echo " CPU调频策略: performance"
# 2. CPU锁定最高频率
echo "[2/5] 锁定CPU最高频率..."
for policy in /sys/devices/system/cpu/cpufreq/policy*/; do
MAX_FREQ=$(cat ${policy}/scaling_max_freq)
echo ${MAX_FREQ} > ${policy}/scaling_min_freq
done
echo " CPU频率已锁定"
# 3. GPU设置为性能模式(节点名以实际 SDK 为准)
echo "[3/5] 配置GPU性能模式..."
GPU_PATH=$(ls -d /sys/class/devfreq/*.gpu 2>/dev/null | head -1)
if [ -n "$GPU_PATH" ]; then
echo performance > ${GPU_PATH}/governor
MAX_FREQ=$(cat ${GPU_PATH}/available_frequencies | awk '{print $NF}')
echo ${MAX_FREQ} > ${GPU_PATH}/min_freq
echo " GPU已设置为性能模式 (${MAX_FREQ}Hz)"
fi
# 4. NPU设置为性能模式(节点名以实际 SDK 为准)
echo "[4/5] 配置NPU性能模式..."
NPU_PATH=$(ls -d /sys/class/devfreq/npu* 2>/dev/null | head -1)
if [ -n "$NPU_PATH" ]; then
echo performance > ${NPU_PATH}/governor
MAX_FREQ=$(cat ${NPU_PATH}/available_frequencies | awk '{print $NF}')
echo ${MAX_FREQ} > ${NPU_PATH}/min_freq
echo " NPU已设置为性能模式"
fi
# 5. 系统参数
echo "[5/5] 优化系统参数..."
echo 1 > /proc/sys/kernel/sched_child_runs_first
echo ""
echo "=== 配置完成 ==="
echo "当前状态:"
echo " CPU0: $(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq)Hz"
echo " CPU4: $(cat /sys/devices/system/cpu/cpu4/cpufreq/scaling_cur_freq)Hz"
echo " GPU: $(cat ${GPU_PATH}/cur_freq 2>/dev/null || echo N/A)Hz"
echo " NPU: $(cat ${NPU_PATH}/cur_freq 2>/dev/null || echo N/A)Hz"5 代码详解
5.1 CPU性能监控工具
5.1.1 perf 性能分析
# 安装perf
sudo apt install linux-tools-$(uname -r)
# 查看CPU性能计数器事件
sudo perf list | head -30
# 记录CPU性能数据 (10秒)
sudo perf record -a -g -o perf.data -- sleep 10
# 分析性能数据
sudo perf report -i perf.data
# 统计CPU缓存命中率
sudo perf stat -e cache-references,cache-misses,instructions,cycles \
-a -- sleep 5
# 监控特定进程
sudo perf top -p <PID>5.1.2 使用mpstat监控多核
# 安装sysstat
sudo apt install sysstat
# 每2秒采样一次CPU使用率, 共10次
mpstat -P ALL 2 10
# 输出示例:
# CPU %usr %nice %sys %iowait %irq %soft %steal %idle
# all 25.34 0.00 5.12 0.23 0.01 0.45 0.00 69.85
# 0 30.12 0.00 6.23 0.11 0.00 0.52 0.00 63.02 (A72)
# 4 15.67 0.00 3.45 0.34 0.01 0.38 0.00 80.15 (A53)
# 查看每个核心的频率
cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq | \
awk '{printf "CPU%d: %d MHz\n", NR-1, $1/1000}'5.1.3 使用top/htop监控
# htop安装和使用
sudo apt install htop
htop
# 在htop中:
# F5: 树状视图
# F6: 按CPU排序
# F9: 发送信号
# t: 显示/隐藏线程
# 按CPU核心分组显示
top -1 -d 2
# 按数字键1: 显示每个CPU核心
# 按P: 按CPU排序
# 按M: 按内存排序5.2 CPU亲和性编程示例
5.2.1 C语言示例
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sched.h>
#include <pthread.h>
#include <time.h>
/* 获取CPU核心数 */
int get_cpu_count(void)
{
return sysconf(_SC_NPROCESSORS_ONLN);
}
/* 获取CPU频率 (KHz) */
unsigned long get_cpu_freq(int cpu)
{
char path[256];
FILE *fp;
unsigned long freq = 0;
snprintf(path, sizeof(path),
"/sys/devices/system/cpu/cpu%d/cpufreq/scaling_cur_freq", cpu);
fp = fopen(path, "r");
if (fp) {
fscanf(fp, "%lu", &freq);
fclose(fp);
}
return freq;
}
/* 将线程绑定到指定CPU核心 */
int pin_thread_to_cpu(pthread_t thread, int cpu_id)
{
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(cpu_id, &cpuset);
return pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset);
}
/* 工作线程函数 */
void *worker_thread(void *arg)
{
int cpu_id = *(int *)arg;
struct timespec start, end;
double elapsed;
volatile long long sum = 0;
/* 绑定到指定CPU */
pin_thread_to_cpu(pthread_self(), cpu_id);
printf("Thread running on CPU%d (freq: %lu KHz)\n",
cpu_id, get_cpu_freq(cpu_id));
/* 计算密集型任务 */
clock_gettime(CLOCK_MONOTONIC, &start);
for (long long i = 0; i < 1000000000LL; i++) {
sum += i * i;
}
clock_gettime(CLOCK_MONOTONIC, &end);
elapsed = (end.tv_sec - start.tv_sec) +
(end.tv_nsec - start.tv_nsec) / 1e9;
printf("CPU%d: %.3f seconds, sum=%lld\n", cpu_id, elapsed, sum);
return NULL;
}
int main(int argc, char *argv[])
{
int cpu_count = get_cpu_count();
pthread_t *threads;
int *cpu_ids;
printf("System has %d CPU cores\n", cpu_count);
printf("Running benchmark on each core...\n\n");
threads = malloc(cpu_count * sizeof(pthread_t));
cpu_ids = malloc(cpu_count * sizeof(int));
for (int i = 0; i < cpu_count; i++) {
cpu_ids[i] = i;
pthread_create(&threads[i], NULL, worker_thread, &cpu_ids[i]);
}
for (int i = 0; i < cpu_count; i++) {
pthread_join(threads[i], NULL);
}
free(threads);
free(cpu_ids);
return 0;
}编译运行:
gcc -o cpu_bench cpu_bench.c -lpthread -O2
./cpu_bench5.2.2 Python示例
#!/usr/bin/env python3
"""
RK3576 CPU/GPU/NPU 性能监控工具
"""
import os
import time
import subprocess
import json
from pathlib import Path
from typing import Dict, List, Optional
class RK3576PerformanceMonitor:
"""RK3576性能监控器"""
CPU_BASE = Path("/sys/devices/system/cpu")
THERMAL_BASE = Path("/sys/class/thermal")
def __init__(self):
self.cpu_count = os.cpu_count()
self._detect_clusters()
self._detect_devfreq_nodes()
def _detect_clusters(self):
"""检测CPU集群配置(RK3576: A72=0-3, A53=4-7)"""
self.clusters = {}
for cpu in range(self.cpu_count):
if cpu < 4:
self.clusters[cpu] = "A72"
else:
self.clusters[cpu] = "A53"
def _detect_devfreq_nodes(self):
"""自动探测 GPU/NPU 的 devfreq 节点"""
devfreq_base = Path("/sys/class/devfreq")
self.gpu_base = None
self.npu_base = None
if devfreq_base.exists():
for node in devfreq_base.iterdir():
if node.name.endswith(".gpu"):
self.gpu_base = node
elif node.name.startswith("npu"):
self.npu_base = node
def get_cpu_info(self) -> List[Dict]:
"""获取所有CPU核心信息"""
info = []
for cpu in range(self.cpu_count):
base = self.CPU_BASE / f"cpu{cpu}" / "cpufreq"
info.append({
"cpu": cpu,
"cluster": self.clusters.get(cpu, "unknown"),
"cur_freq": self._read_file(base / "scaling_cur_freq"),
"max_freq": self._read_file(base / "scaling_max_freq"),
"min_freq": self._read_file(base / "scaling_min_freq"),
"governor": self._read_file(base / "scaling_governor"),
})
return info
def get_gpu_info(self) -> Dict:
"""获取GPU信息"""
if not self.gpu_base:
return {"error": "GPU device not found"}
return {
"cur_freq": self._read_file(self.gpu_base / "cur_freq"),
"max_freq": self._read_file(self.gpu_base / "max_freq"),
"governor": self._read_file(self.gpu_base / "governor"),
}
def get_npu_info(self) -> Dict:
"""获取NPU信息"""
if not self.npu_base:
return {"error": "NPU device not found"}
return {
"cur_freq": self._read_file(self.npu_base / "cur_freq"),
"max_freq": self._read_file(self.npu_base / "max_freq"),
"governor": self._read_file(self.npu_base / "governor"),
}
def get_temperatures(self) -> Dict[str, float]:
"""获取所有温度"""
temps = {}
for tz_dir in self.THERMAL_BASE.glob("thermal_zone*"):
zone_type = self._read_file(tz_dir / "type")
zone_temp = self._read_file(tz_dir / "temp")
if zone_type and zone_temp:
try:
temps[zone_type] = int(zone_temp) / 1000.0
except (ValueError, TypeError):
pass
return temps
def print_status(self):
"""打印完整性能状态"""
print("=" * 65)
print("RK3576 Performance Status")
print("=" * 65)
# CPU
print("\n[Cores]")
for info in self.get_cpu_info():
freq_mhz = int(info["cur_freq"]) // 1000 if info["cur_freq"] else 0
print(f" CPU{info['cpu']} ({info['cluster']}): "
f"{freq_mhz} MHz | gov={info['governor']}")
# GPU
gpu = self.get_gpu_info()
gpu_mhz = int(gpu["cur_freq"]) // 1000000 if gpu.get("cur_freq") else 0
print(f"\n[GPU] {gpu_mhz} MHz | gov={gpu.get('governor', 'N/A')}")
# NPU
npu = self.get_npu_info()
if "error" not in npu:
npu_mhz = int(npu["cur_freq"]) // 1000000 if npu.get("cur_freq") else 0
print(f"[NPU] {npu_mhz} MHz | gov={npu.get('governor', 'N/A')}")
# 温度
temps = self.get_temperatures()
if temps:
print("\n[Temperatures]")
for zone, temp in temps.items():
print(f" {zone}: {temp:.1f} C")
print("=" * 65)
@staticmethod
def _read_file(path: Path) -> Optional[str]:
try:
return path.read_text().strip()
except (FileNotFoundError, PermissionError):
return None
def main():
monitor = RK3576PerformanceMonitor()
try:
while True:
monitor.print_status()
time.sleep(2)
except KeyboardInterrupt:
print("\nMonitoring stopped.")
if __name__ == "__main__":
main()运行:
chmod +x rk3576_monitor.py
sudo python3 rk3576_monitor.py5.3 GPU基准测试
# 使用glmark2测试GPU
# DRM模式 (适用于无桌面环境)
glmark2-drm
# Wayland模式
glmark2-wayland
# 2D测试
glmark2-drm --run-vertex-transform
# 查看GPU详细信息(节点名以实际 SDK 为准)
GPU_PATH=$(ls -d /sys/class/devfreq/*.gpu | head -1)
cat ${GPU_PATH}/trans_stat
# GPU负载监控
watch -n 1 "cat ${GPU_PATH}/cur_freq; \
cat ${GPU_PATH}/trans_stat | head -5"5.4 NPU推理基准测试
/*
* NPU推理示例 (使用rknpu2 API)
* 文件: npu_benchmark.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <rknn_api.h>
/* 创建RKNN上下文 */
static rknn_context create_rknn_context(const char *model_path)
{
rknn_context ctx;
int ret;
ret = rknn_init(&ctx, (void *)model_path, 0, 0, NULL);
if (ret < 0) {
fprintf(stderr, "rknn_init failed: %d\n", ret);
return -1;
}
return ctx;
}
/* 测试不同核心配置的推理性能(核心枚举值以实际 rknpu2 头文件为准) */
void benchmark_core_configs(const char *model_path)
{
struct {
int core_mask;
const char *desc;
} configs[] = {
{ RKNN_NPU_CORE_AUTO, "Auto" },
{ RKNN_NPU_CORE_0, "Core 0" },
{ RKNN_NPU_CORE_0_1, "Core 0+1" },
};
int num_configs = sizeof(configs) / sizeof(configs[0]);
printf("NPU Benchmark: %s\n", model_path);
printf("%-12s | %10s | %8s\n", "Config", "Time(ms)", "FPS");
printf("%-12s-+-%10s-+-%8s\n", "------------", "----------", "--------");
for (int i = 0; i < num_configs; i++) {
rknn_context ctx = create_rknn_context(model_path);
if (ctx < 0) continue;
/* 设置NPU核心掩码(枚举值以实际 SDK 为准) */
rknn_set_core_mask(ctx, configs[i].core_mask);
/* 获取输入输出信息 */
rknn_input_output_num io_num;
rknn_query(ctx, RKNN_QUERY_IN_OUT_NUM, &io_num,
sizeof(io_num));
/* 分配输入缓冲区 */
rknn_input inputs[io_num.n_input];
memset(inputs, 0, sizeof(inputs));
for (int j = 0; j < io_num.n_input; j++) {
inputs[j].index = j;
inputs[j].type = RKNN_TENSOR_UINT8;
inputs[j].fmt = RKNN_TENSOR_NHWC;
inputs[j].size = 224 * 224 * 3;
inputs[j].buf = calloc(1, inputs[j].size);
}
/* 预热 */
for (int w = 0; w < 5; w++) {
rknn_inputs_set(ctx, io_num.n_input, inputs);
rknn_output outputs[io_num.n_output];
memset(outputs, 0, sizeof(outputs));
for (int j = 0; j < io_num.n_output; j++) {
outputs[j].want_float = 1;
}
rknn_run(ctx, NULL);
rknn_outputs_get(ctx, io_num.n_output, outputs, NULL);
rknn_outputs_release(ctx, io_num.n_output, outputs);
}
/* 正式测试 */
struct timespec start, end;
int iterations = 50;
clock_gettime(CLOCK_MONOTONIC, &start);
for (int t = 0; t < iterations; t++) {
rknn_inputs_set(ctx, io_num.n_input, inputs);
rknn_output outputs[io_num.n_output];
memset(outputs, 0, sizeof(outputs));
for (int j = 0; j < io_num.n_output; j++) {
outputs[j].want_float = 1;
}
rknn_run(ctx, NULL);
rknn_outputs_get(ctx, io_num.n_output, outputs, NULL);
rknn_outputs_release(ctx, io_num.n_output, outputs);
}
clock_gettime(CLOCK_MONOTONIC, &end);
double elapsed = (end.tv_sec - start.tv_sec) +
(end.tv_nsec - start.tv_nsec) / 1e9;
double avg_ms = (elapsed / iterations) * 1000.0;
double fps = iterations / elapsed;
printf("%-12s | %10.2f | %8.1f\n",
configs[i].desc, avg_ms, fps);
/* 清理 */
for (int j = 0; j < io_num.n_input; j++) {
free(inputs[j].buf);
}
rknn_destroy(ctx);
}
}
int main(int argc, char *argv[])
{
if (argc < 2) {
fprintf(stderr, "Usage: %s <model.rknn>\n", argv[0]);
return 1;
}
benchmark_core_configs(argv[1]);
return 0;
}编译:
gcc -o npu_benchmark npu_benchmark.c \
-lrknpu2 -I/usr/include/rknpu2 -O2
./npu_benchmark model.rknn示例中 NPU 核心掩码枚举值(
RKNN_NPU_CORE_*)以实际发布的 rknpu2 头文件为准(待板上确认)。
6 常见问题
6.1 CPU频率无法提升
| 问题 | 原因 | 解决方案 |
|---|---|---|
| CPU锁定在低频 | thermal throttling | 检查温度: cat /sys/class/thermal/thermal_zone*/temp |
| 无法切换governor | 权限不足 | 使用 sudo 执行 |
| 频率跳变不稳定 | schedutil参数过保守 | 调小 rate_limit_us |
| 某些核心不上频 | EAS调度策略 | 设置 performance governor |
# 诊断CPU频率问题
echo "=== CPU温度 ==="
cat /sys/class/thermal/thermal_zone0/temp
echo "=== 当前governor ==="
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
echo "=== 频率范围 ==="
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq
echo "=== 当前频率 ==="
cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq
# 如果thermal导致降频, 可以临时提高阈值(请谨慎操作)
echo 95000 | sudo tee /sys/class/thermal/thermal_zone0/trip_point_0_temp6.2 GPU性能不足
| 问题 | 原因 | 解决方案 |
|---|---|---|
| GPU频率上不去 | governor设置 | 切换到 performance |
| 3D渲染卡顿 | 频率波动大 | 锁定最高频率 |
| OpenCL慢 | 未使用GPU | 确认程序使用GPU而非CPU |
# GPU性能排查(节点名以实际 SDK 为准)
GPU_PATH=$(ls -d /sys/class/devfreq/*.gpu | head -1)
echo "=== GPU信息 ==="
cat ${GPU_PATH}/cur_freq
cat ${GPU_PATH}/governor
# 设置GPU性能模式
echo performance | sudo tee ${GPU_PATH}/governor6.3 NPU无法达到6 TOPS
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 推理速度慢 | 未使用全部NPU核心 | 设置合适的 core mask |
| NPU频率低 | governor未设为performance | 切换governor |
| 模型未优化 | INT8量化 | 使用RKNN工具进行量化 |
| 内存带宽瓶颈 | DDR频率低 | 检查DDR频率配置 |
# NPU状态检查(节点名以实际 SDK 为准)
NPU_PATH=$(ls -d /sys/class/devfreq/npu* | head -1)
cat ${NPU_PATH}/cur_freq
cat ${NPU_PATH}/governor
# 设置NPU性能模式
echo performance | sudo tee ${NPU_PATH}/governor
# 查看NPU驱动加载状态
dmesg | grep -i "rknpu"
lsmod | grep rknpu
# RKNN模型转换优化 (使用rknn-toolkit2, 以实际 SDK 版本为准)
python3 -c "
import rknn.api
rknn = rknn.api.RKNN()
rknn.config(mean_values=[[128,128,128]],
std_values=[[128,128,128]],
target_platform='rk3576')
rknn.load_rknn('model.rknn')
print('RKNN model loaded successfully')
"
target_platform参数值需与实际使用的 RKNN 工具链版本匹配(待板上确认)。
6.4 实时任务延迟高
# 诊断实时性能
# 1. 检查内核是否支持PREEMPT_RT
zcat /proc/config.gz | grep CONFIG_PREEMPT
# CONFIG_PREEMPT=y (标准内核)
# CONFIG_PREEMPT_RT=y (RT内核, 需要单独编译)
# 2. 检查中断亲和性
cat /proc/interrupts | head -20
# 3. 设置CPU隔离 (排除后台任务)
# 在内核启动参数中添加:
# isolcpus=4-7 (隔离A53核心给实时任务)
# 或
# isolcpus=2-3 (隔离部分A72核心)
# 4. 禁用CPU频率变化 (实时任务要求)
echo performance | sudo tee /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
# 5. 测量任务切换延迟
sudo cyclictest -t8 -p99 -i1000 -l10000 -m
# -t8: 8个线程
# -p99: 最高优先级
# -i1000: 1ms间隔
# -l10000: 运行10000次
# -m: 锁定内存
# 6. 查看中断分布
watch -n 1 "cat /proc/interrupts | grep -E 'GIC|ethernet|usb'"6.5 功耗与散热问题
# 监控温度变化趋势
for i in $(seq 1 60); do
temp=$(cat /sys/class/thermal/thermal_zone0/temp)
echo "$(date '+%H:%M:%S') CPU: $((temp/1000))°C"
sleep 1
done
# 检查散热风扇状态
cat /sys/class/thermal/cooling_device*/type
cat /sys/class/thermal/cooling_device*/cur_stateM4-R2 底板是否提供风扇控制接口以底板原理图(S-04)为准。
6.6 big.LITTLE调度异常
# 查看EAS调度状态
cat /proc/sys/kernel/sched_energy_aware
# 确保为1
# 查看任务分布
ps -eo pid,psr,comm --sort=-pcpu | head -20
# psr: 运行在哪个CPU
# 手动迁移高负载任务到大核
taskset -c 0-3 ./heavy_computation
# 查看调度器统计
cat /proc/schedstat
cat /proc/sched_debug | head -507 相关文档
| 文档名称 | 说明 | 路径 |
|---|---|---|
| 系统启动时间优化 | 启动流程与系统级优化 | 系统启动时间优化 |
| 内存与存储优化 | 内存管理与存储性能优化 | 内存与存储优化 |
| 功耗分析与优化 | 低功耗设计与功耗管理 | 功耗分析与优化 |
| 调试工具使用指南 | 常用调试与性能分析工具 | 调试工具使用指南 |
| NPU 架构与性能概览 | RK3576 NPU 架构与算力说明 | NPU架构与性能概览 |
| NPU 性能调优 | NPU 推理性能优化 | NPU性能调优 |
| RKNN-Toolkit2 | RKNN 模型转换与量化工具 | 模型转换与量化 |
