首页
商城
  • English
  • 简体中文
首页
商城
  • English
  • 简体中文
  • 产品系列

    • FPGA+ARM

      • GM-3568JHF

        • 一、简介

          • GM-3568JHF 简介
        • 二、快速开始

          • 00 前言
          • 01 环境搭建
          • 02 编译说明
          • 03 烧录指南
          • 04 调试工具
          • 05 软件更新
          • 06 查看信息
          • 07 测试命令
          • 08 应用编译
          • 09 源码获取
        • 三、外设与接口

          • 01 USB
          • 02 显示与触摸
          • 03 以太网
          • 04 WIFI
          • 05 蓝牙
          • 06 TF-Card
          • 07 音频
          • 08 串口
          • 09 CAN
          • 10 RTC
        • 四、应用开发

          • 01 UART读写案例
          • 02 按键检测案例
          • 03 LED灯闪烁案例
          • 04 MIPI屏幕检测案例
          • 05 读取 USB 设备信息案例
          • 06 FAN 检测案例
          • 07 FPGA FSPI 通信案例
          • 08 FPGA DMA 读写案例
          • 09 GPS调试案例
          • 10 以太网测试案例
          • 11 RS485读写案例
          • 12 FPGA IIC 读写案例
          • 13 PN532 NFC读卡案例
          • 14 TF卡读写案例
        • 五、QT开发

          • 01 ARM64交叉编译器环境搭建
          • 02 QT 程序加入开机自启服务
        • 六、RKNN_NPU开发

          • 01 RK3568 NPU 概述
          • 02 开发环境搭建
          • 运行官方 YOLOv5 示例
        • 七、FPGA开发

          • ARM与FPGA通讯
          • FPGA开发手册
        • 八、其他

          • 01 根目录文件系统的修改
          • 02 系统自启服务
        • 九、资料下载

          • 资料下载
    • ShimetaPi

      • M4-R1

        • 一、简介

          • M4-R1简介
        • 二、快速上手

          • 01 OpenHarmony概述
          • 02 镜像烧录
          • 03 应用开发快速上手
          • 04 设备开发快速上手
        • 三、应用开发

          • 01 ArkUI

            • 1 ArkTS语言简介
            • 2 UI 组件-Row 容器介绍
            • 3 UI 组件-Column 容器介绍
            • 4 UI 组件-Text 组件
            • 5 UI 组件-Toggle 组件
            • 6 UI 组件-Slider 组件
            • 7 UI 组件-Animation 组件&Transition 组件
          • 02 资料获取

            • 1 OpenHarmony 官方资料
          • 03 开发须知

            • 1 Full-SDK替换教程
            • 2 引入和使用三方库
            • 3 HDC调试
            • 4 命令行恢复出厂模式
            • 5 升级App为system权限
          • 04 构建第一个应用

            • 1 构建第一个ArkTs应用-HelloWorld
          • 05 案例

            • 01 串口调试助手应用案例
            • 02 手写板应用案例
            • 03 数字时钟应用案例
            • 04 WIFI 信息获取应用案例
        • 四、设备开发

          • 1 Ubuntu环境开发

            • 01 环境搭建
            • 02 下载源码
            • 03 编译源码
          • 2 使用DevEco Device Tool 工具

            • 01 工具简介
            • 02 开发环境的搭建
            • 03 导入SDK
            • 04 HUAWEI DevEco Tool 功能介绍
        • 五、内核外设与接口

          • 01 指南
          • 02 设备树介绍
          • 03 NAPI 入门
          • 04 ArkTS入门
          • 05 NAPI开发实战演示
          • 06 GPIO介绍
          • 07 I2C通讯
          • 08 SPI通信
          • 09 PWM 控制
          • 10 串口通讯
          • 11 TF卡
          • 12 屏幕
          • 13 触摸
          • 14 Ethernet(以太网)
          • 15 M.2 硬盘
          • 16 音频
          • 17 WIFI & BT
          • 18 摄像头
        • 六、资料下载

          • 资料下载
      • M4-R2

        • 一、产品简介

          • M4-R2 产品简介
        • 二、快速上手

          • 快速上手
        • 三、Android 系统

          • 1 快速上手

            • Android系统烧录与启动
            • 开发环境搭建
            • ADB调试与日志分析
            • SDK下载与编译环境搭建
            • Android系统基础操作
          • 2 SDK 编译

            • Android_SDK编译
            • Android构建系统与增量编译
          • 3 系统开发

            • Android系统定制
          • 4 应用开发

            • Android应用开发入门
            • Android JNI开发
          • 5 驱动与 HAL

            • Android HAL开发
          • 6 AI 与 NPU

            • Android NPU使用指南
        • 四、硬件参考

          • 核心板参数
          • 底板接口定义
          • 40PIN引脚定义
          • 电源管理
        • 五、常见问题与故障排除

          • 系统启动问题
          • 外设驱动问题
          • 网络连接问题
          • 显示问题
          • 常见编译错误
        • 六、应用方案参考

          • 智能显示终端方案
          • 边缘AI计算方案
          • 工业控制方案
          • NVR安防监控方案
          • 智能家居网关方案
        • 七、资料下载

          • 资料下载
      • M5-R2A

        • 一、产品简介

          • M5-R2A 产品简介
        • 二、快速上手

          • 系统烧录指南
          • 开发环境搭建
          • 快速上手
          • SDK下载与编译环境搭建
        • 四、Debian/Ubuntu 系统

          • 1 快速上手

            • 系统启动与基础操作
            • 网络配置与SSH
            • 软件包管理与更新
            • Debian 与 Ubuntu 镜像差异
          • 2 系统开发

            • Linux SDK编译
            • 内核配置与裁剪
            • 设备树详解与实践
            • 根文件系统构建
          • 3 外设驱动开发

            • GPIO驱动与控制
            • I2C驱动开发
            • SPI驱动开发
            • UART串口驱动
            • PWM驱动
            • ADC驱动
            • CAN/CAN-FD驱动
            • USB主机与设备驱动
            • SDMMC/eMMC驱动
            • 以太网GMAC驱动
            • 音频驱动
            • 摄像头Camera驱动
            • 触摸屏驱动
            • 显示DRM驱动
            • HDMI显示驱动
            • PCIe驱动
            • WiFi/蓝牙驱动
            • 看门狗WDT驱动
            • 热敏传感器THERMAL驱动
          • 4 应用开发

            • C/C++应用开发入门
            • Python应用开发
            • Qt嵌入式开发实战
            • GStreamer多媒体开发
            • 网络编程与应用
            • 文件系统与存储
          • 5 AI 与 NPU

            • NPU架构与性能概览
            • RKNN Toolkit2安装与使用
            • 模型转换与量化
            • 分类模型部署(LeNet/ResNet)
            • 目标检测部署(YOLOv5/v7/v8)
            • 语义分割部署
            • 人脸检测与识别
            • OCR文字识别
            • NPU性能调优与调试
          • 6 多媒体

            • 显示框架
            • 摄像头应用
            • 视频编解码(MPP)
            • 音频开发与ALSA
            • RGA图像处理
          • 7 性能优化与调试

            • 系统启动时间优化
            • CPU/GPU/NPU调优
            • 内存与存储优化
            • 功耗分析与优化
            • 调试工具使用指南
          • 8 高级主题

            • 安全启动与加密
            • OTA远程升级
            • Docker容器部署
            • ROS/ROS2机器人开发
            • RTOS与Linux协同
        • 五、Android 系统

          • 1 快速上手

            • Android系统烧录与启动
            • Android系统基础操作
            • ADB调试与日志分析
          • 2 SDK 编译

            • Android SDK编译
            • Android构建系统与增量编译
          • 3 系统开发

            • Android系统定制
          • 4 应用开发

            • Android应用开发入门
            • Android JNI开发
          • 5 驱动与 HAL

            • Android HAL开发
          • 6 AI 与 NPU

            • Android NPU使用指南
        • 六、硬件参考

          • 核心板参数
          • 底板接口定义
          • 40PIN引脚定义
          • 电源管理
        • 七、资料下载

          • 资料下载
      • Pico-G1

        • 一、产品概述

          • 01 产品介绍
          • 02 SDK版本基本信息
        • 二、快速入门

          • 01 开发环境搭建
          • 02 镜像编译
          • 03 镜像烧录
          • 04 系统登录
          • 05 网络配置
          • 06 文件传输
          • 07 SDK目录结构
          • 08 部署第一个应用程序
          • 09 部署第一个驱动程序
          • 10 SD卡挂载
        • 三、外设与接口

          • 01 GPIO控制
          • 02 UART串口通信
          • 03 I2C 通信
          • 04 SPI 通信
        • 四、MPP媒体开发

          • 01 MPP媒体处理软件
          • 02 图像处理链路
          • 03 视频输入
          • 04 图像编码
        • 五、NPU与AI

          • 01 NPU驱动与运行库架构
          • 02 .xmm 模型加载
          • 03 SVP视频处理
          • 04 AI降噪 (AI_NR)
        • 六、应用程序示例

          • 01 加解密接口应用
          • 02 ADC 采集应用
          • 03 低功耗应用
          • 04 音频处理应用
          • 05 视频编码应用
          • 06 视频输入应用
          • 07 视频图形子系统应用
          • 08 区域叠加应用
          • 09 智能视频引擎应用
          • 10 UVC 网络摄像头应用
          • 11 综合快速演示应用
          • 12 FPN 校正应用
          • 13 区域运动检测应用
          • 14 MTCNN 人脸检测应用
        • 七、扩展板外设功能例程

          • 00 - Pico 扩展板外设功能例程总览
          • 01 - OLED 显示应用
          • 02 - TFT 显示应用
          • 03 - MPU6050 陀螺仪应用
          • 04 - ADC 采集应用
          • 05 - 无源蜂鸣器应用
          • 06 - MQ 气体传感器应用
          • 07 - GPS 定位应用
          • 08 - SHT20 温湿度应用
          • 09 - 超声波测距应用
          • 10 - SPO2 血氧传感器应用
          • 11 - 电机控制应用
          • 12 - 舵机控制应用
    • 开源鸿蒙

      • SC-3568HA

        • 一、简介

          • SC-3568HA简介
        • 二、快速上手

          • OpenHarmony概述
          • 镜像烧录
          • 开发环境准备
          • Hello World应用以及部署
        • 三、应用开发

          • ArkUI

            • 第一章 ArkTS语言简介
            • 第二章 UI组件介绍和实际应用(上)
            • 第三章 UI组件介绍和实际应用(中)
            • 第四章 UI组件介绍和实际应用(下)
          • 拓展

            • 第一章 入门指引
            • 第二章 三方库的引用和使用
            • 第三章 应用编译以及部署
            • 第四章 命令行恢复出厂设置
            • 第五章 系统调试--HDC调试
            • 第六章 APP 稳定性测试
            • 第七章 应用测试
        • 四、设备开发

          • 第一章 环境搭建
          • 第二章 下载源码
          • 第三章 编译源码
        • 五、内核的外设与接口

          • 树莓派接口
          • GPIO 接口
          • I2C 接口
          • SPI通信
          • PWM控制
          • 串口通讯
          • TF Card
          • 屏幕
          • 触摸
          • 音频
          • RTC
          • Ethernet
          • M.2
          • MINI-PCIE
          • Camera
          • WIFI&BT
          • 树莓派拓展板
        • 六、资料下载

          • 资料下载
      • M-K1HSE

        • 一、简介

          • M-K1HSE 简介
        • 二、快速开始

          • 开发环境搭建
          • 源码获取
          • 编译说明
          • 烧录指南
        • 三、应用开发

          • 00 应用开发环境搭建
          • 01 第一个应用-Hello World
        • 四、外设与接口

          • 01 Audio
          • 02 RS485
          • 03 Display
        • 五、系统定制开发

          • 系统移植
          • 系统定制
          • 驱动开发
          • 系统调试
          • OTA升级
        • 六、资料下载

          • 资料下载
    • HVS视觉融合相机

      • 快速开始

        • 01 SDK 介绍
        • 02 资料下载
        • 03 设备固件烧录
        • 04 第一个 C++ 程序
        • 05 第一个 Python 程序
        • 06 Python 数据分析
        • 07 MultiVision Studio
        • 08 版本介绍
      • 二次开发

        • 01 编程指引

          • 01 打开相机
          • 02 读取事件
          • 03 录制与回放
          • 04 事件处理
          • 05 显示与可视化
          • 06 调参
          • 07 采集 APS 图像
          • 08 帧率切换
          • 09 时间戳同步
        • 02 Toolkit SDK

          • 01 Hybrid Vision Toolkit
          • 02 快速上手
          • 03 C++ API
          • 04 Python API
        • 03 Algo SDK

          • 01 Hybrid Vision Algo
          • 02 Algo API
          • 03 Windows Algo SDK
        • 04 USB数据协议
        • 05 示例程序总览
        • 06 应用场景
      • 基础知识

        • 01 事件相机基础原理
        • 02 HVS 融合视觉
        • 03 事件可视化
        • 04 数据格式参考
        • 05 术语表
        • 06 偏置与调参
        • 07 视频教程
      • HVS 相机

        • 01 HVS 相机快速上手
        • 02 网络化能力

          • 01 HVS 相机系统架构
          • 2 EVS Network Server
          • 3 EVS Time Sync
          • 4 Web Window
        • 03 HVS 相机兼容性矩阵
        • 04 常见问题解决指南
        • 05 产品

          • CF-NRS1(灵光一号视觉融合相机)
      • HVS 模块

        • 01 MIPI 模块快速上手
        • 02 载板适配

          • RDK X5 载板适配
          • RDK S100 载板适配
          • 树莓派载板适配
          • shimetapi 板载板适配
        • 03 MIPI 模块兼容性矩阵
        • 04 产品

          • EVS_003 传感器模块
    • AI硬件

      • 1684XB-32T

        • 一、简介

          • AIBOX-1684XB-32简介
        • 二、快速上手

          • 初次使用
          • 网络配置
          • 磁盘使用
          • 内存分配
          • 风扇策略
          • 固件升级
          • 交叉编译
          • 模型量化
        • 三、应用开发

          • 开发简介

            • Sophgo SDK开发
            • SOPHON-DEMO简介
          • 大语言模型

            • 部署Llama3示例
            • Sophon LLM_api_server开发
            • 部署MiniCPM-V-2_6
            • Qwen-2-5-VL图片视频识别DEMO
            • Qwen3-chat-DEMO
            • Qwen3-Qwen Agent-MCP开发
            • Qwen3-langchain-AI Agent
          • 深度学习

            • ResNet(图像分类)
            • LPRNet(车牌识别)
            • SAM(通用图像分割基础模型)
            • YOLOv5(目标检测)
            • OpenPose(人体关键点检测)
            • PP-OCR(光学字符识别)
        • 四、资料下载

          • 资料下载
      • 1684X-416T

        • 简介

          • AIBOX-1684X-416简介
        • Demo简单操作指引

          • shimeta智慧监控demo的简单使用说明
      • RDK-X5

        • 简介

          • RDK-X5 硬件简介
        • 快速开始

          • RDK-X5 快速开始
        • 应用开发

          • AI在线模型开发

            • 实验01-接入火山引擎豆包 AI
            • 实验02-图片分析
            • 实验03-多模态视觉分析定位
            • 实验04-多模态图文比较分析
            • 实验05-多模态文档表格分析
            • 实验06-摄像头运用-AI视觉分析
          • 大语言模型

            • 实验01-语音识别
            • 实验02-语音对话
            • 实验03-多模态图片分析-语音对话
            • 实验04-多模态图片比较-语音对话
            • 实验05-多模态文档分析-语音对话
            • 实验06-多模态视觉运用-语音对话
          • ROS2基础开发

            • 实验01-搭建环境
            • 实验02-工作包的创建及编译
            • 实验03-运行 ROS2 话题通信节点
            • 实验04-ROS2 相机应用
          • 40pin-IO开发

            • 实验01-GPIO 输出(LED闪烁)
            • 实验02-GPIO 输入
            • 实验03-按键控制 LED
            • 实验04-PWM 输出
            • 实验05-串口输出
            • 实验06-IIC 实验
            • 实验07-SPI 实验
          • USB模块开发使用

            • 实验01-USB 语音模块使用
            • 实验02-声源定位模块使用
          • 机器视觉技术实战

            • 实验01-打开 USB 摄像头
            • 实验02-颜色识别检测
            • 实验03-手势识别体验
            • 实验04-YOLOv5物体检测
      • RDK-S100

        • 简介

          • RDK-S100 硬件简介
        • 快速开始

          • RDK-S100 硬件简介
        • 应用开发

          • AI在线模型开发

            • 实验01-接入火山引擎豆包 AI
            • 实验02-图片分析
            • 实验03-多模态视觉分析定位
            • 实验04-多模态图文比较分析
            • 实验05-多模态文档表格分析
            • 实验06-摄像头运用-AI视觉分析
          • 大语言模型

            • 实验01-语音识别
            • 实验02-语音对话
            • 实验03-多模态图片分析-语音对话
            • 实验04-多模态图片比较-语音对话
            • 实验05-多模态文档分析-语音对话
            • 实验06-多模态视觉运用-语音对话
          • ROS2基础开发

            • 实验01-搭建环境
            • 实验02-工作包的创建及编译
            • 实验03-运行 ROS2 话题通信节点
            • 实验04-ROS2 相机应用
          • 40pin-IO开发

            • 实验01-GPIO 输出(LED闪烁)
            • 实验02-GPIO 输入
            • 实验03-按键控制 LED
            • 实验04-PWM 输出
            • 实验05-串口输出
            • 实验06-IIC 实验
            • 实验07-SPI 实验
          • USB模块开发使用

            • 实验01-USB 语音模块使用
            • 实验02-声源定位模块使用
          • 机器视觉技术实战

            • 实验01-打开 USB 摄像头
            • 实验02-图像处理基础
            • 实验03-目标检测
            • 实验04-图像分割
      • AIBOX-M88(RK1828)

        • 一、简介

          • AIBOX-M88(RK1828) - 产品介绍
          • AIBOX-M88(RK1828) 硬件规格
          • AIBOX-M88(RK1828) 使用与安全
        • 二、快速开始

          • AIBOX-M88(RK1828) 镜像烧录
          • RK182X 硬件安装与验证
          • RK182X 开发环境快速搭建
          • RK182X SDK 总览
          • RK182X 环境搭建详解
          • RK182X 快速开始
          • 原厂 SDK 资料抽取记录
        • 三、开发指南

          • ClawChips 架构与原理
          • SKILL 使用手册
          • RK182X系列LLM推理(RK1828型号)
          • RK182X系列CNN推理(RK1828型号)
          • 模型转换
          • RK182X AI Agent 应用开发指南
          • RK182X 工业异常检测应用
        • 四、SDK 参考

          • RKNN3-SDK 概述

            • RKNN3 SDK 概述
          • RKNN3-Toolkit

            • RKNN3 Toolkit 安装与使用
          • RKLLM

            • RKLLM 设备端 LLM 推理
          • RK182X系列 NPU 概述与架构(RK1828型号)
          • RK182X INT8 量化推理部署
          • RK182X MPP 多媒体处理框架
          • MPP 详解

            • RK182X 视频解码
            • RK182X 视频编码
          • NPU 详解

            • RKNN 模型转换
            • RK182X NPU INT8 量化推理
            • RK182X 多模型并行推理
          • RGA 详解

            • RK182X RGA 2D 图形加速
          • VPU 详解

            • RK182X VPU 编解码
        • 五、硬件参考

          • RK182X系列 硬件架构概述(RK1828型号)
          • RK182X 引脚定义与复用配置
          • RK182X 引脚定义
          • RK182X 电源管理
          • RK182X 时钟与 PLL 配置
          • RK182X 时钟与频率配置
        • 六、实战教程

          • Hello World
          • Hello RK1828 - 第一个程序
          • RTSP 推流
          • RTSP 推流 + AI 分析
          • 视美泰AI龙虾一键部署
          • PaddleOCR-VL 文字识别
          • Qwen3-1.7B LLM 文本对话
          • AI 巡检多视角(Qwen3-VL 包装)
          • YOLOv5 目标检测
        • 七、资料下载

          • 资料下载
        • 八、常见问题

          • 常见问题
    • 核心板

      • C-3568BQ

        • 简介

          • C-3568BQ 简介
      • C-3588LQ

        • 简介

          • C-3588LQ 简介
      • GC-3568JBAF

        • 简介

          • GC-3568JBAF 简介
      • C-K1BA

        • 简介

          • C-K1BA 简介
    • 软件平台

      • ShiMetaPi Workbench

        • 一、产品简介

          • 产品概述
          • 核心架构
          • 功能入口
          • 支持的硬件
          • 版本说明
        • 二、快速入门

          • 安装与登录
          • 连接设备
          • 配置环境
          • 接入 AIHub
          • 首次调用模型
        • 三、用户指南

          • 工作区总览
          • 设备管理
          • 模型广场
          • 一键部署
          • 视觉 - SVP
          • 视觉 - 自定义模型
          • shimeta-py IDE
          • 终端
          • Agent 调试助手
          • 设置与资源
        • 四、常见问题

          • 安装与登录
          • 设备连接
          • 模型与部署
          • 视觉与运行时
          • 设置与其他
      • ShimetaPi软件源

        • 简介

          • ShimetaPi 软件源
        • Pico G1 (GK7206)

          • 快速开始

            • 安装与首次推理
            • shimeta_infer — 图片推理
            • shimeta_camera — 摄像头实时推理
            • SVP 场景检测
            • 文件传输与内置模型参考
            • 常见问题
          • HTTP API & Python SDK

            • HTTP API 参考
      • 模型微调训练平台

        • 一、平台介绍

          • 模型训练平台
        • 二、快速上手

          • 注册与登录
          • 创建第一个模型(30 分钟快速体验)
        • 三、训练指南

          • 数据准备与标注
          • 训练参数配置
          • 启动与监控训练
          • 模型评估与测试
        • 四、模型部署

          • 导出模型
          • 部署到边缘设备

RK3588 Linux CPU/GPU/NPU 性能调优指南

硬件平台: C-3588LQ V1.0 核心板 + SHIMETAPI-M5-R2A V1.0 底板
软件环境: Linux 6.1, Debian 12 / Ubuntu 22.04
文档版本: v1.0
更新日期: 2026-08-19


1 概述

1.1 文档目的

这篇指南讲解 RK3588 平台在 Linux 6.1 内核下如何调 CPU、GPU、NPU 三个部件的性能,内容包括调频策略配置(调频由 governor 决定,它是内核里的一套策略模块,负责根据负载决定频率升还是降,后面会反复用到)、任务调度优化、功耗管理、性能监控和基准测试。调优的本质是在性能、功耗和散热之间找平衡,读完你就能按自己的场景做出取舍。

1.2 RK3588 处理器架构

先认识芯片内部的结构。RK3588 是大小核(big.LITTLE)架构:4 个 Cortex-A76 大核干重活,4 个 Cortex-A55 小核处理轻负载;GPU 是 Mali-G610 MP4,NPU 有 3 个核心、算力 6 TOPS:

┌─────────────────────────────────────────────────────────────┐
│                     RK3588 SoC                              │
│                                                             │
│  ┌─────────────────────────┐  ┌─────────────────────────┐  │
│  │   Cortex-A76 Cluster    │  │   Cortex-A55 Cluster    │  │
│  │   (Big Core)            │  │   (Little Core)         │  │
│  │                         │  │                         │  │
│  │  CPU0: 2.4 GHz         │  │  CPU4: 1.8 GHz         │  │
│  │  CPU1: 2.4 GHz         │  │  CPU5: 1.8 GHz         │  │
│  │  CPU2: 2.4 GHz         │  │  CPU6: 1.8 GHz         │  │
│  │  CPU3: 2.4 GHz         │  │  CPU7: 1.8 GHz         │  │
│  └─────────────────────────┘  └─────────────────────────┘  │
│                                                             │
│  ┌─────────────────────┐  ┌───────────────────────────────┐│
│  │  Mali-G610 MP4 GPU  │  │  NPU (6 TOPS, 3 cores)       ││
│  │  up to 1.0 GHz     │  │  fdab0000.npu                 ││
│  └─────────────────────┘  └───────────────────────────────┘│
└─────────────────────────────────────────────────────────────┘

1.3 调优目标分类

动手前先明确你要什么,不同目标对应不同的策略组合:

调优目标典型场景优先策略
最大性能AI推理、视频编码、3D渲染performance governor, 最高频率
均衡模式桌面交互、多媒体播放schedutil governor, 动态调频
最低功耗待机、传感器采集powersave governor, 最低频率
实时响应工业控制、音频处理RT调度, CPU绑定, 中断亲和性

2 硬件准备

2.1 硬件平台信息

组件规格说明
核心板C-3588LQ V1.08nm工艺, 集成RK3588
底板SHIMETAPI-M5-R2A V1.0扩展接口底板
CPU4×A76 + 4×A55big.LITTLE架构
GPUMali-G610 MP4支持OpenCL 3.0
NPU6 TOPS, 3核心支持INT8/INT16/FP16
散热需主动散热大负载必须加风扇

2.2 散热方案建议

性能调优的前提是散热跟得上。RK3588 满载功耗可达 15-20W,必须配散热片和风扇,否则芯片过热降频,调优成果会被温度吃掉。按负载选方案:

散热方案参考:
├── 轻负载 (< 8W):   被动散热片 (铝制, >= 40mm×40mm×10mm)
├── 中负载 (8-12W):  散热片 + 低速风扇
└── 重负载 (> 12W):  散热片 + 高速风扇 + 导热硅脂

2.3 电源要求

供电同样不能凑合,功率不足会带来系统不稳定和意外降频:

推荐供电:
- 5V/4A (20W) DC电源适配器 (至少)
- 使用底板DC接口供电, 避免USB供电功率不足
- 供电不足会导致系统不稳定和意外降频

3 软件准备

3.1 系统环境

先确认系统版本符合预期:

# 确认内核版本
uname -r
# 预期输出: 6.1.x-rockchip

# 确认系统信息
cat /etc/os-release
# Ubuntu 22.04.x LTS / Debian 12.x

# 确认CPU信息
lscpu | head -20

3.2 必要软件包安装

把后面要用到的性能工具、NPU 工具(Rockchip 提供)和编译工具一次装齐:

# 更新系统
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

# 安装NPU工具 (Rockchip提供)
sudo apt install -y \
    rktool \
    rknn-toolkit2 \
    rknpu2

# 安装编译工具
sudo apt install -y \
    build-essential \
    cmake \
    pkg-config \
    libdrm-dev

3.3 验证硬件节点

后面的调优基本都靠读写 sysfs 节点完成(sysfs 是内核暴露出来的虚拟文件系统,/sys 下的那些文件),先确认这些节点都存在:

# 检查CPU频率节点
ls /sys/devices/system/cpu/cpu0/cpufreq/
# 应存在: scaling_governor, scaling_max_freq, scaling_cur_freq 等

# 检查GPU频率节点
ls /sys/class/devfreq/fb000000.gpu/
# 应存在: governor, cur_freq, max_freq, min_freq

# 检查NPU设备
ls /sys/class/devfreq/fdab0000.npu/
# 应存在: governor, cur_freq, max_freq

# 检查thermal区域
ls /sys/class/thermal/thermal_zone*/
# RK3588通常有多个thermal zone (CPU, GPU, NPU等)

4 操作步骤

4.1 CPU 调频策略配置

4.1.1 查看当前CPU状态

CPU 频率由内核的 cpufreq 子系统管理,governor 决定频率怎么随负载变化。动手前先看清本机现状,逐条执行并对照注释里的结果:

# ⚠ 勘误:本机 cpu0-3 是 A55 小核、cpu4-7 是 A76 大核(与部分资料相反)!
# 且默认 governor 是 ondemand(不是 schedutil)

# 查看当前调频策略( ondemand)
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

# 查看当前频率
cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq

# 查看可用频率范围
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies
# A55(cpu0-3): 408000 ... 1800000(8 档,最高 1.8GHz)
cat /sys/devices/system/cpu/cpu4/cpufreq/scaling_available_frequencies
# A76(cpu4-7): 408000 ... 2016000 2208000 2256000(11 档,最高 2.256GHz)

# 查看可用调频策略( 7 种)
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors
# interactive conservative ondemand userspace powersave performance schedutil

# 本机 cpufreq policy 结构(3 个集群: policy0/4/6)
ls /sys/devices/system/cpu/cpufreq/
# policy0  policy4  policy6
# policy0=cpu0-3(A55)  policy4=cpu4-5(A76)  policy6=cpu6-7(A76)

特别注意开头那条勘误:本机 cpu0-3 是 A55 小核、cpu4-7 是 A76 大核,与部分资料的写法相反,后面绑定核心时别弄反。下面是同一忙循环基准(cpu4)下三种 governor 的对比,powersave 会把频率锁在 408MHz,慢了 5.7 倍:

governor循环耗时(3 次平均)说明
performance491.0 ms锁 2.256GHz
ondemand497.6 ms动态,很快升满
powersave2790.3 ms锁 408MHz,慢 5.7 倍

4.1.2 设置CPU调频策略

切换 governor 就是往对应的 sysfs 节点写一个词。方法一用循环写节点(临时生效,重启后恢复默认),方法二用 cpufreq-set 工具,效果一样:

# 方法一: 临时设置 (重启失效)
# 全部核心设置为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   # A76集群
sudo cpufreq-set -c 4-7 -g powersave     # A55集群

4.1.3 schedutil 参数调优

schedutil 是由内核调度器直接驱动的 governor,比 ondemand 响应更快,它的 rate_limit_us 参数控制两次调频之间的最小间隔。本机默认 governor 是 ondemand,policy0 下没有 schedutil/ 子目录,想调参数得先把 governor 切过去:

# 注意:本机默认 governor 是 ondemand,policy0 下没有 schedutil/ 子目录!
# 想调 schedutil 参数先切 governor:
echo schedutil | sudo tee /sys/devices/system/cpu/cpufreq/policy0/scaling_governor
cat /sys/devices/system/cpu/cpufreq/policy0/schedutil/rate_limit_us
echo 500 | sudo tee /sys/devices/system/cpu/cpufreq/policy0/schedutil/rate_limit_us

# ondemand 的等效参数(默认 governor 下直接可用):
cat /sys/devices/system/cpu/cpufreq/policy0/ondemand/sampling_rate

4.2 GPU 频率调节

4.2.1 查看GPU状态

GPU 的调频接口走 devfreq 框架(可以理解成设备版的 cpufreq,GPU、NPU 这类非 CPU 设备都用它管理频率),操作方式同样是读写 sysfs 节点:

# GPU设备路径
GPU_PATH="/sys/class/devfreq/fb000000.gpu"   # 本机 GPU 节点(fde40000 不存在)

# 查看GPU当前频率
cat ${GPU_PATH}/cur_freq
# 单位: Hz

# 查看GPU可用频率
cat ${GPU_PATH}/available_frequencies

# 查看GPU调频策略
cat ${GPU_PATH}/governor

# 查看GPU负载
cat ${GPU_PATH}/trans_stat

下面是本机 fb000000.gpu 节点的实际值,后面几行是 governor 切换的验证过程,写入 performance 后频率立即锁到 1GHz:

cur_freq = 300000000          ← 空闲 300MHz
governor = simple_ondemand
available_frequencies = 1000000000 900000000 ... 300000000(8 档,最高 1GHz)

# governor 切换
echo performance | sudo tee ${GPU_PATH}/governor
cat ${GPU_PATH}/cur_freq     # → 1000000000(立即锁 1GHz)
echo simple_ondemand | sudo tee ${GPU_PATH}/governor   # 恢复

4.2.2 GPU性能模式设置

需要压榨 GPU 时锁定最高频率,跑完测试记得切回动态调频并恢复默认频率范围,不然白费电:

# 设置GPU为性能模式 (锁定最高频率)
echo performance | sudo tee ${GPU_PATH}/governor

# 手动锁定GPU频率到最高
GPU_PATH="/sys/class/devfreq/fb000000.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默认频率范围
echo 200000000 | sudo tee ${GPU_PATH}/min_freq
echo 1000000000 | sudo tee ${GPU_PATH}/max_freq

4.2.3 GPU频率与功耗对照

频率越高功耗越高,按场景选够用的档位即可:

GPU频率典型功耗适用场景
200 MHz~0.5W2D显示、静态UI
400 MHz~1.2W视频播放、轻度3D
600 MHz~2.0W中度3D、游戏
800 MHz~3.0W重度3D、GPU计算
1000 MHz~4.5W满性能3D、OpenCL

4.3 NPU 配置

4.3.1 查看NPU状态

NPU 也通过 devfreq 管理,设备节点是 fdab0000.npu:

# NPU设备路径( fdab0000.npu,不是 fdab0000.npu——那是 RK356x 的地址)
NPU_PATH="/sys/class/devfreq/fdab0000.npu"

# 查看NPU当前频率
cat ${NPU_PATH}/cur_freq

# 查看NPU可用频率
cat ${NPU_PATH}/available_frequencies

# 查看NPU调频策略
cat ${NPU_PATH}/governor

4.3.2 NPU性能模式

设置方法和 GPU 一样,一点差别是本机 NPU 的动态调频 governor 叫 rknpu_ondemand,不是 simple_ondemand:

# 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设置为动态调频(本机 governor 名是 rknpu_ondemand,不是 simple_ondemand)
echo rknpu_ondemand | sudo tee ${NPU_PATH}/governor

# 本机 NPU devfreq:
#   cur_freq = 1000000000 (1GHz)
#   available_frequencies = 300M ~ 1000M 共 8 档
#   governor = rknpu_ondemand

4.3.3 NPU核心选择

RK3588 的 NPU 有 3 个核心,跑 RKNN 模型推理时可以通过 API 指定用哪几个,让不同模型互不抢核:

# RK3588 NPU有3个核心, 通过rknpu2库可以指定使用的核心
# 在RKNN模型推理时通过API选择:
# - RKNN_NPU_CORE_AUTO:  自动分配
# - RKNN_NPU_CORE_0:     仅核心0
# - RKNN_NPU_CORE_1:     仅核心1
# - RKNN_NPU_CORE_2:     仅核心2
# - RKNN_NPU_CORE_0_1:   使用核心0和1
# - RKNN_NPU_CORE_0_1_2: 使用全部3个核心

# 查看NPU设备信息
cat /sys/kernel/debug/rknpu/version 2>/dev/null || echo "需root权限"
dmesg | grep -i npu | head -10

4.4 CPU 亲和性与任务调度

4.4.1 CPU亲和性设置

CPU 亲和性(affinity)就是把某个进程固定在指定核心上运行,避免它在大核小核之间来回漂移。taskset 是最常用的绑核工具,后台杂活绑给小核,性能敏感任务绑给大核:

# 查看进程CPU亲和性
taskset -p <PID>

# ⚠ 本机: cpu0-3 是 A55 小核、cpu4-7 是 A76 大核
# 绑定到A55小核(后台任务)
taskset -c 0-3 ./background_task

# 绑定到A76大核(性能敏感任务)
taskset -c 4-7 ./my_application

# 同一忙循环(2 亿次加法):
#   taskset -c 0 → 552.6 ms (A55)
#   taskset -c 4 → 497.6 ms (A76)
# 简单整数循环收益有限(~11%,受限于循环本身);
# 真实计算密集任务(如 NPU 推理前处理)用 A76 收益更明显

# 使用numactl (如可用)
numactl --cpunodebind=0 --membind=0 ./my_application

# 查看CPU拓扑
lscpu -e
# 或
cat /sys/devices/system/cpu/cpu*/topology/physical_package_id
cat /sys/devices/system/cpu/cpu*/topology/core_type

代码注释里有数据:同一个忙循环绑 A76 只比 A55 快约 11%,这类简单整数循环本身是瓶颈;换成真实计算密集任务(比如 NPU 推理前处理),大核的收益会明显得多。

4.4.2 big.LITTLE 调度策略

不手动绑核时,内核的 EAS(Energy Aware Scheduling,节能感知调度)会自动把任务往省电的核心上安排。相关状态可以这样查看:

# 查看EAS (Energy Aware Scheduling) 状态
cat /proc/sys/kernel/sched_energy_aware
# 1 = 启用, 0 = 禁用

# 查看CPU容量值 (A76 > A55)
cat /sys/devices/system/cpu/cpu0/cpu_capacity
# A76: 1024 (最大)
cat /sys/devices/system/cpu/cpu4/cpu_capacity
# A55: 600-700 左右

# 查看调度器域
ls /proc/sys/kernel/sched_domain/cpu0/

4.4.3 实时调度配置

对延迟敏感的任务(音频处理、工业控制)可以用实时调度策略,设置工具是 chrt。SCHED_FIFO 按优先级抢占普通进程,SCHED_DEADLINE 更进一步,按「每个周期保证多少运行时间」的契约调度:

# 设置进程为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(温度监测区)的类型和温度打印一遍:

# 查看所有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整体温度

# 本机 7 个 zone(空负载时):
# soc-thermal: 39.769°C   bigcore0-thermal: 39.769°C
# bigcore1-thermal: 39.769°C   littlecore-thermal: 39.769°C
# center-thermal: 39.769°C  gpu-thermal: 38.846°C  npu-thermal: 38.846°C

4.5.2 温控策略配置

内核温控靠 trip point(温度触发点)工作:到 passive 点开始降频,到 active 点开风扇,到 critical 点直接关机保护硬件。触发温度可以改,单位是毫摄氏度:

# 查看温控触发点
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_speed

4.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}'"

4.6 DVFS (动态电压频率调节) 配置

4.6.1 DVFS参数查看

DVFS 指动态电压频率调节:负载低时降频降压省电,负载高时升频保性能。前面改的 governor 其实就是 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

# 查看freq_table
cat /sys/devices/system/cpu/cpufreq/policy0/scaling_available_frequencies

# GPU DVFS
cat /sys/class/devfreq/fb000000.gpu/available_frequencies
cat /sys/class/devfreq/fb000000.gpu/available_transitions

4.6.2 DVFS锁定频率

跑基准测试前通常要把频率锁死,免得测试过程中自动升降频污染数据。做法是把最低频率和最高频率写成同一个值:

# 锁定CPU到最高频率
echo 1800000 | sudo tee /sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq   # A55 上限 1.8G
echo 408000  | sudo tee /sys/devices/system/cpu/cpufreq/policy0/scaling_min_freq

# 锁定CPU到特定频率 (例如1.6GHz)
echo 1608000 | sudo tee /sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq
echo 1608000 | sudo tee /sys/devices/system/cpu/cpufreq/policy0/scaling_min_freq

# 恢复默认频率范围
echo 408000 | sudo tee /sys/devices/system/cpu/cpufreq/policy0/scaling_min_freq
echo 1800000 | sudo tee /sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq   # A55 上限 1.8G

4.7 一键性能配置脚本

不想每次手敲命令的话,把前面 CPU、GPU、NPU 的设置动作合成一个脚本,一键进入性能模式:

#!/bin/bash
# rk3588_performance_setup.sh
# RK3588 一键性能模式配置脚本

set -e

echo "=== RK3588 性能模式配置 ==="

# 检查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设置为性能模式
echo "[3/5] 配置GPU性能模式..."
GPU_PATH="/sys/class/devfreq/fb000000.gpu"
if [ -d "$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设置为性能模式
echo "[4/5] 配置NPU性能模式..."
NPU_PATH="/sys/class/devfreq/fdab0000.npu"
if [ -d "$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. 禁用powersave
echo "[5/5] 优化系统参数..."
echo 1 > /proc/sys/kernel/sched_child_runs_first
echo performance > /sys/devices/system/cpu/cpufreq/policy*/scaling_governor 2>/dev/null

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 是 Linux 自带的性能剖析工具,能借助 CPU 硬件计数器统计指令数、缓存命中等指标,也能对全系统采样找出热点函数:

# 安装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监控多核

mpstat 属于 sysstat 套件,适合分别查看每个核心各自的使用率,确认负载有没有落在预期的核心上:

# 安装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  (A76)
#   4    15.67  0.00   3.45   0.34     0.01    0.38   0.00    80.15  (A55)

# 查看每个核心的频率
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监控

日常快速查看用 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语言示例

命令行绑核适合临时任务,程序内部绑核要用 pthread 的 affinity 接口。这个示例在所有核心上各起一个线程跑同样的计算,同时读出每个核心的实时频率,可以直接当基准测试用:

#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_bench

5.2.2 Python示例

这个脚本把前面用过的那些 sysfs 节点读取逻辑封装成一个循环监控器,每 2 秒打印一次 CPU、GPU、NPU 的频率、governor 和各处温度:

#!/usr/bin/env python3
"""
RK3588 CPU/GPU/NPU 性能监控工具
"""

import os
import time
import subprocess
import json
from pathlib import Path
from typing import Dict, List, Optional

class RK3588PerformanceMonitor:
    """RK3588性能监控器"""

    CPU_BASE = Path("/sys/devices/system/cpu")
    GPU_BASE = Path("/sys/class/devfreq/fb000000.gpu")
    NPU_BASE = Path("/sys/class/devfreq/fdab0000.npu")
    THERMAL_BASE = Path("/sys/class/thermal")

    def __init__(self):
        self.cpu_count = os.cpu_count()
        self._detect_clusters()

    def _detect_clusters(self):
        """检测CPU集群配置"""
        self.clusters = {}
        for cpu in range(self.cpu_count):
            policy_path = self.CPU_BASE / f"cpu{cpu}" / "cpufreq" / "policy"
            if policy_path.exists():
                policy_dir = list(policy_path.parent.iterdir())[0] \
                    if policy_path.is_dir() else policy_path
            # 简化: A76=0-3, A55=4-7
            if cpu < 4:
                self.clusters[cpu] = "A76"
            else:
                self.clusters[cpu] = "A55"

    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信息"""
        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.exists():
            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("RK3588 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 = RK3588PerformanceMonitor()
    try:
        while True:
            monitor.print_status()
            time.sleep(2)
    except KeyboardInterrupt:
        print("\nMonitoring stopped.")


if __name__ == "__main__":
    main()

运行:

chmod +x rk3588_monitor.py
sudo python3 rk3588_monitor.py

5.3 GPU基准测试

glmark2 是常用的 OpenGL 基准测试,会跑一组场景并给出总分,适合对比 GPU 调优前后的差异:

# 使用glmark2测试GPU
# DRM模式 (适用于无桌面环境)
glmark2-drm

# Wayland模式
glmark2-wayland

# 2D测试
glmark2-drm --run-vertex-transform

# 查看GPU详细信息
cat /sys/class/devfreq/fb000000.gpu/trans_stat

# GPU负载监控
watch -n 1 "cat /sys/class/devfreq/fb000000.gpu/cur_freq; \
    cat /sys/class/devfreq/fb000000.gpu/trans_stat | head -5"

5.4 NPU推理基准测试

这份 C 代码用 rknpu2 的 API 分别测试 NPU 单核、双核、三核等配置下的推理速度,跑完就知道你的模型适合哪种核心组合:

/*
 * NPU多核推理示例 (使用rknpu2 API)
 * 文件: npu_benchmark.c
 */

#include <stdio.h>
#include <stdlib.h>
#include <rknn_api.h>
#include <rknn_matmul_api.h>

/* 选择NPU核心进行推理 */
static rknn_context create_rknn_context(const char *model_path,
                                         int core_mask)
{
    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;
    }

    /* 设置NPU核心掩码 */
    ret = rknn_set_core_mask(ctx, core_mask);
    if (ret < 0) {
        fprintf(stderr, "rknn_set_core_mask failed: %d\n", ret);
        rknn_destroy(ctx);
        return -1;
    }

    return ctx;
}

/* 测试不同核心配置的推理性能 */
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_1,        "Core 1"    },
        { RKNN_NPU_CORE_2,        "Core 2"    },
        { RKNN_NPU_CORE_0_1,      "Core 0+1"  },
        { RKNN_NPU_CORE_0_1_2,    "All 3"     },
    };

    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,
                                                configs[i].core_mask);
        if (ctx < 0) continue;

        /* 获取输入输出信息 */
        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

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_temp

6.2 GPU性能不足

GPU 的问题多半出在 governor 设置和频率波动上:

问题原因解决方案
GPU频率上不去governor设置切换到 performance
3D渲染卡顿频率波动大锁定最高频率
OpenCL慢未使用GPU确认程序使用GPU而非CPU
# GPU性能排查
echo "=== GPU信息 ==="
cat /sys/class/devfreq/fb000000.gpu/cur_freq
cat /sys/class/devfreq/fb000000.gpu/governor

# 设置GPU性能模式
echo performance | sudo tee /sys/class/devfreq/fb000000.gpu/governor

# 检查GPU是否在使用
cat /sys/kernel/debug/dri/0/state | grep -A5 "fb000000.gpu"

6.3 NPU无法达到6 TOPS

推理速度上不来时,按下面的表逐项排查,多数情况是核心没用满或模型没量化:

问题原因解决方案
推理速度慢未使用全部NPU核心设置 RKNN_NPU_CORE_0_1_2
NPU频率低governor未设为performance切换governor
模型未优化INT8量化使用RKNN工具进行量化
内存带宽瓶颈DDR频率低检查DDR频率配置
# NPU状态检查
cat /sys/class/devfreq/fdab0000.npu/cur_freq
cat /sys/class/devfreq/fdab0000.npu/governor

# 设置NPU性能模式
echo performance | sudo tee /sys/class/devfreq/fdab0000.npu/governor

# 查看NPU驱动加载状态
dmesg | grep -i "rknpu"
lsmod | grep rknpu

# RKNN模型转换优化 (使用rknn-toolkit2)
python3 -c "
import rknn.api
rknn = rknn.api.RKNN()
rknn.config(mean_values=[[128,128,128]],
            std_values=[[128,128,128]],
            target_platform='rk3588')
rknn.load_rknn('model.rknn')
print('RKNN model loaded successfully')
"

6.4 实时任务延迟高

实时性问题的排查思路:先确认内核有没有实时支持(PREEMPT_RT 实时补丁,标准内核没有,需要单独编译),再检查中断和调度干扰,最后用 cyclictest(实时延迟测试工具)量化延迟:

# 诊断实时性能
# 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 (隔离A55核心给实时任务)
# 或
# isolcpus=2-3 (隔离部分A76核心)

# 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 功耗与散热问题

温度异常或功耗偏高时,按下面的命令检查供电、风扇和温度趋势:

# 监控功耗 (如硬件支持)
cat /sys/class/power_supply/*/power_now 2>/dev/null

# 检查散热风扇状态
cat /sys/class/thermal/cooling_device*/type
cat /sys/class/thermal/cooling_device*/cur_state

# 设置风扇策略
# active cooling: 温度达到阈值时开启风扇
cat /sys/class/thermal/thermal_zone*/trip_point_1_type
# active

# 监控温度变化趋势
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

6.6 big.LITTLE调度异常

任务总是跑错核心时,先查 EAS 开关是否打开,再看任务实际分布在哪些核心上,必要时手动迁移:

# 查看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 -50

# 查看CPU负载均衡
cat /proc/schedstat | awk '{print $2}' | sort -rn

7 相关文档

文档名称说明路径
RK3588 Linux开发指南Rockchip官方Linux开发文档S-01
C-3588LQ核心板规格书核心板硬件规格S-02
SHIMETAPI-M5-R2A底板原理图底板电路设计S-03
RK3588 TRM技术参考手册Rockchip官网
Linux Kernel Documentation - CPUFreqCPU调频文档内核源码Documentation/
Mali-G610 GPU用户手册GPU开发指南Arm Developer
在 GitHub 上编辑此页
Prev
系统启动时间优化
Next
内存与存储优化