RK3576 内存与存储优化指南
目标平台: RK3576 | NPU 算力: 6 TOPS | 文档版本: V1.0
适用板型: C-3576BQ 核心板 + M4-R2 底板
最后更新: 2026-10-23
1. 概述
RK3576 SoC 搭载 LPDDR5 内存控制器,M4-R2 板载 LPDDR5 内存(标配 4GB)。存储方面提供 eMMC(标配 32GB,控制器节点以实际 SDK 为准)、TF 卡(SD 3.0)以及 M.2 SSD 插槽(扩展存储)。平台集成 DMA 高速 DMA 控制器和 IOMMU。
本文档覆盖:LPDDR5 调优、内存带宽测试、eMMC 性能优化、M.2 SSD 配置、TF 卡优化、文件系统调优(ext4/f2fs/btrfs)、zram/zswap 内存压缩、DMA 缓存与 IOMMU、内存碎片整理、overcommit 调优、huge pages 以及内存泄漏检测。
说明:RK3576 具体的 DDR 最高频率、DMC 设备树节点、eMMC/SD 控制器基地址以实际发布的 RK3576 SDK 为准(待板上确认)。
1.1 应用场景
- 高性能计算:LPDDR5 高带宽支撑多路视频并发处理和 AI 推理
- 高速数据采集:M.2 SSD 作为传感器数据、摄像头视频流的高速写入介质
- 内存受限优化:通过 zram/zswap 压缩回收可用内存,扩展有效容量
- DMA 批量传输:DMA 控制器在内存与外设间搬移大量数据,降低 CPU 占用
- IOMMU 安全隔离:为存储/显示等设备启用地址翻译与访问隔离
1.2 硬件资源总览
| 模块 | 设备树节点 | 寄存器基地址 | 功能描述 |
|---|---|---|---|
| 内存控制器 | — | bootloader 初始化 | LPDDR5(标配 4GB) |
| eMMC 控制器 | sdhci@<base_addr> | 以实际 SDK 为准 | eMMC(标配 32GB) |
| TF 卡控制器 | sdmmc@<base_addr> | 以实际 SDK 为准 | SD 3.0,最大支持 128GB |
| M.2 SSD 插槽 | 以实际 SDK 为准 | 以实际 SDK 为准 | 扩展存储(M.2 接口) |
| DMA 控制器 | — | 以实际 SDK 为准 | 高速 DMA 数据搬移 |
| IOMMU | smmu@<base_addr> | 以实际 SDK 为准 | 地址翻译与隔离 |
上表节点名为平台通用结构示例,RK3576 实际的设备树节点名与寄存器基地址以实际发布的 RK3576 SDK 为准(待板上确认)。
2. 硬件准备
2.1 硬件清单
| 组件 | 型号/规格 | 备注 |
|---|---|---|
| 主控板 | C-3576BQ 核心板 + ShimetaPi M4-R2 V10 底板 | LPDDR5 4GB + eMMC 32GB |
| M.2 SSD(可选) | M.2 接口 SSD | 接入底板 M.2 插槽 |
| TF 卡(可选) | microSD 卡(SD 3.0,最大 128GB) | TF 卡座 |
| 调试串口线 | USB 转 TTL 3.3V | 波特率 1500000 |
| 电源 | 5V/2A(Type-C 或 6pin) | M4-R2 供电 |
2.2 硬件确认
# 内存信息
cat /proc/meminfo | head -5
# MemTotal: 3684880 kB (4GB 配置示例)
# DDR 频率(需 root)
dmesg | grep -i "lpddr\|dram\|memory"
# eMMC 设备
lsblk -o NAME,SIZE,TYPE,MOUNTPOINT
# NAME SIZE TYPE MOUNTPOINT
# mmcblk0 29.1G disk
# M.2 SSD
lsblk -o NAME,SIZE,TYPE,MOUNTPOINT | grep -E "nvme|NAME"
# TF 卡
ls /dev/mmcblk1*2.3 设备树 Overlay 配置(M.2 SSD 扩展)
LABEL rk3576-linux
KERNEL /boot/vmlinuz-6.1.0-1011-rockchip
FDT /boot/dtbs/6.1.0-1011-rockchip/rk3576-xxx.dtb
FDTOVERLAYS /boot/dtbs/6.1.0-1011-rockchip/overlays/rk3576-m2.dtbo
APPEND root=/dev/mmcblk0p2 rootfstype=ext4 rw console=ttyS2,1500000n8M.2 SSD 的设备树 overlay 名称与配置方式以实际发布的 RK3576 SDK 为准(待板上确认)。
3. 软件准备
3.1 必要工具
sudo apt-get update
sudo apt-get install -y \
util-linux e2fsprogs f2fs-tools btrfs-progs \
nvme-cli mmc-utils sysstat numactl dmidecode \
stress-ng sysbench fio hdparm memtester3.2 内核配置确认
uname -r
# 期望: 6.1.x-xxx-rockchip
lsmod | grep -E "mmc_block|nvme|zram|zswap"
zgrep CONFIG_ZSWAP /proc/config.gz
zgrep CONFIG_IOMMU /proc/config.gz
grep -i huge /proc/meminfo4. 操作步骤
4.1 LPDDR5 内存调优
4.1.1 查看内存频率与时序
# DMC (Dynamic Memory Controller) 节点
ls /sys/class/devfreq/dmc/
cat /sys/class/devfreq/dmc/cur_freq
cat /sys/class/devfreq/dmc/available_frequencies
# 具体频率档位以实际 SDK 为准4.1.2 调整 DDR 频率
# 锁定 performance 模式
echo performance | sudo tee /sys/class/devfreq/dmc/governor
# 锁定最高频率
MAX_FREQ=$(cat /sys/class/devfreq/dmc/available_frequencies | awk '{print $NF}')
echo $MAX_FREQ | sudo tee /sys/class/devfreq/dmc/min_freq
echo $MAX_FREQ | sudo tee /sys/class/devfreq/dmc/max_freq
# 验证
cat /sys/class/devfreq/dmc/cur_freq
# 恢复动态调频
echo ondemand | sudo tee /sys/class/devfreq/dmc/governor4.2 内存带宽基准测试
4.2.1 STREAM Benchmark
cd /tmp
wget -q https://www.cs.virginia.edu/stream/FTP/Code/stream.c -O stream.c
gcc -O2 -fopenmp -DSTREAM_ARRAY_SIZE=80000000 -DNTIMES=20 stream.c -o stream -lm
export OMP_NUM_THREADS=$(nproc)
./stream
# 实际带宽以板端实测为准(待板上验证)4.2.2 内存稳定性测试
# 4GB 内存配置下建议使用较小测试块
sudo memtester 256M 1
# 期望: 所有 16 项测试均显示 ok
free -h4.3 eMMC 性能优化
4.3.1 性能测试
# 缓存读取速度
sudo hdparm -Tt /dev/mmcblk0
# 顺序读写测试(分区以实际布局为准)
fio --name=emmc_seq --filename=/dev/mmcblk0p2 \
--rw=read --bs=128k --size=512M --numjobs=1 --runtime=30 --group_reporting
# 4K 随机读写
fio --name=emmc_rand --filename=/dev/mmcblk0p2 \
--rw=randread --bs=4k --size=256M --numjobs=4 --runtime=30 --group_reporting4.3.2 预读与 I/O 调度器调优
# 设置预读值(2MB)
sudo blockdev --setra 4096 /dev/mmcblk0
# I/O 调度器设为 none
echo none | sudo tee /sys/block/mmcblk0/queue/scheduler4.3.3 挂载优化与 TRIM
# 在线应用优化挂载选项
sudo mount -o remount,noatime,nodiratime,commit=60,discard /
# fstab 持久化
# /dev/mmcblk0p2 / ext4 errors=remount-ro,noatime,nodiratime,commit=60,discard 0 1
# 定期 TRIM
sudo fstrim -v /
# eMMC 健康状态
sudo mmc extcsd read /dev/mmcblk0 | grep -i "life\|health"4.4 M.2 SSD 优化
4.4.1 设备检测与调优
# M.2 SSD 挂载后通常为 /dev/nvme0n1
lsblk
# I/O 调度器设为 none
echo none | sudo tee /sys/block/nvme0n1/queue/scheduler
# 调整队列深度与预读
echo 2048 | sudo tee /sys/block/nvme0n1/queue/nr_requests
sudo blockdev --setra 4096 /dev/nvme0n14.4.2 FIO 基准测试
# 顺序读取
fio --name=seqread --ioengine=libaio --direct=1 --bs=128k \
--rw=read --size=1G --numjobs=4 --runtime=30 --group_reporting \
--filename=/dev/nvme0n1
# 随机 4K 读取
fio --name=randread --ioengine=libaio --direct=1 --bs=4k \
--rw=randread --size=256M --numjobs=8 --iodepth=32 --runtime=30 \
--group_reporting --filename=/dev/nvme0n1
# 随机 4K 写入
fio --name=randwrite --ioengine=libaio --direct=1 --bs=4k \
--rw=randwrite --size=256M --numjobs=8 --iodepth=32 --runtime=30 \
--group_reporting --filename=/dev/nvme0n1M.2 SSD 的实际读写速率取决于 SSD 型号与 M.2 接口协商的链路规格(待板上验证)。
4.4.3 格式化与挂载
sudo mkfs.ext4 -L m2_data /dev/nvme0n1
sudo mkdir -p /mnt/m2
sudo mount /dev/nvme0n1 /mnt/m2
echo '/dev/nvme0n1 /mnt/m2 ext4 defaults,noatime,nodiratime,discard 0 2' | sudo tee -a /etc/fstab注意:M4-R2 的 M.2 插槽支持的 SSD 接口类型(NVMe/SATA)与供电规格以底板原理图(S-04)为准。
4.5 TF 卡优化
sudo blockdev --setra 2048 /dev/mmcblk1
fio --name=sd_read --filename=/dev/mmcblk1 --rw=read --bs=64k --size=256M --numjobs=1 --runtime=30 --group_reporting
# TF 卡按 SD 3.0 协议工作,实际速率以卡与控制器协商结果为准(待板上验证)4.6 文件系统优化
4.6.1 ext4 调优
sudo mkfs.ext4 -O ^has_journal,^metadata_csum -E stride=128,stripe-width=256 -m 1 -b 4096 /dev/nvme0n1p1
sudo mount -o noatime,nodiratime,discard,commit=60 /dev/nvme0n1p1 /mnt/m2
sudo tune2fs -m 1 /dev/nvme0n1p1
sudo tune2fs -o journal_data_writeback /dev/nvme0n1p14.6.2 f2fs 调优(推荐 eMMC/TF 卡)
sudo mkfs.f2fs -f /dev/mmcblk0p3
sudo mount -o discard,noatime,extent_cache=on,active_logs=6,mode=adaptive /dev/mmcblk0p3 /mnt/emmc4.6.3 btrfs 调优(推荐 M.2 大容量)
sudo mkfs.btrfs -f -d single -m single -s 4096 /dev/nvme0n1p1
sudo mount -o noatime,ssd,compress=zstd:3,space_cache=v2 /dev/nvme0n1p1 /mnt/m24.7 内存压缩:zram / zswap
4.7.1 zram 快速配置
sudo modprobe zram num_devices=1
echo lz4 | sudo tee /sys/block/zram0/comp_algorithm
# 设置为物理内存 50%(4GB 配置下约为 2GB)
ZRAM_SIZE=$(($(awk '/MemTotal/{print $2}' /proc/meminfo) / 2))
echo ${ZRAM_SIZE}k | sudo tee /sys/block/zram0/disksize
sudo mkswap /dev/zram0
sudo swapon -p 100 /dev/zram0
free -h
# 监控压缩率
cat /sys/block/zram0/mm_stat4.7.2 zram 持久化
sudo tee /usr/local/bin/setup-zram.sh << 'EOF'
#!/bin/bash
modprobe zram num_devices=1
echo lz4 > /sys/block/zram0/comp_algorithm
ZRAM_SIZE=$(($(awk '/MemTotal/{print $2}' /proc/meminfo) / 2))
echo ${ZRAM_SIZE}k > /sys/block/zram0/disksize
mkswap /dev/zram0 && swapon -p 100 /dev/zram0
EOF
sudo chmod +x /usr/local/bin/setup-zram.sh
sudo tee /etc/systemd/system/zram.service << 'EOF'
[Unit]
Description=Setup zram swap for RK3576
Before=swap.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/setup-zram.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload && sudo systemctl enable zram.service4.7.3 zswap 配置
# 内核启动参数追加: zswap.enabled=1 zswap.compressor=zstd zswap.max_pool_percent=30
sudo sysctl -w vm.zswap.enabled=1
sudo sysctl -w vm.zswap.compressor=zstd
sudo sysctl -w vm.zswap.max_pool_percent=30
sudo tee /etc/sysctl.d/99-zswap.conf << 'EOF'
vm.zswap.enabled = 1
vm.zswap.compressor = zstd
vm.zswap.max_pool_percent = 30
EOF
sudo sysctl --system4.7.4 swappiness 调优
# zram 场景建议 60-100,传统 swap 建议 10-30
sudo sysctl -w vm.swappiness=60
echo "vm.swappiness = 60" | sudo tee -a /etc/sysctl.d/99-swap.conf4.8 DMA 缓存与 IOMMU
4.8.1 DMA 测试
ls /sys/class/dma/
sudo modprobe dmatest
echo 100 | sudo tee /sys/module/dmatest/parameters/iterations
echo 1048576 | sudo tee /sys/module/dmatest/parameters/test_buf_size
sudo sh -c 'echo 1 > /sys/module/dmatest/parameters/run'
dmesg | tail -10
# 期望: summary 100 tests, 0 failures, 0 errors4.8.2 IOMMU 配置
ls /sys/kernel/iommu_groups/
dmesg | grep -i "smmu\|iommu"
# IOMMU 相关配置(以实际 SDK 内核配置为准)
# arm-smmu 相关内核参数
sudo sysctl -w vm.zone_reclaim_mode=0
echo "vm.zone_reclaim_mode = 0" | sudo tee -a /etc/sysctl.d/99-performance.conf4.9 内存碎片整理与 overcommit 调优
4.9.1 碎片整理
cat /proc/buddyinfo
echo 1 | sudo tee /proc/sys/vm/compact_memory
cat /proc/vmstat | grep -E "compact_|pgcompact"4.9.2 overcommit 调优
sudo sysctl -w vm.overcommit_memory=0
sudo sysctl -w vm.overcommit_ratio=80
sudo tee /etc/sysctl.d/99-memory.conf << 'EOF'
vm.overcommit_memory = 0
vm.overcommit_ratio = 80
EOF4.9.3 Huge Pages
grep -i huge /proc/meminfo
echo 1024 | sudo tee /proc/sys/vm/nr_hugepages
echo "vm.nr_hugepages = 1024" | sudo tee /etc/sysctl.d/99-hugepages.conf
sudo sysctl --system
sudo mkdir -p /mnt/huge
sudo mount -t hugetlbfs nodev /mnt/huge说明:4GB 内存配置下请谨慎分配大页,避免影响系统其他进程内存使用。
4.10 内存泄漏检测
# 进程内存监控
watch -n 2 'ps aux --sort=-%mem | head -20'
# valgrind 检测
valgrind --leak-check=full --show-leak-kinds=all ./your_application
# 进程内存历史记录
PID=<目标PID>
for i in $(seq 1 60); do
echo "$(date +%H:%M:%S) $(awk '/VmRSS/ {print $2}' /proc/$PID/status) kB" >> /tmp/rss_log.txt
sleep 10
done5. 代码详解
5.1 DMC 频率控制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#define DMC_FREQ_PATH "/sys/class/devfreq/dmc/cur_freq"
#define DMC_GOVERNOR "/sys/class/devfreq/dmc/governor"
#define DMC_AVAIL_FREQ "/sys/class/devfreq/dmc/available_frequencies"
#define DMC_MIN_FREQ "/sys/class/devfreq/dmc/min_freq"
#define DMC_MAX_FREQ "/sys/class/devfreq/dmc/max_freq"
static int write_sysfs(const char *path, const char *value)
{
int fd = open(path, O_WRONLY);
if (fd < 0) { perror(path); return -1; }
int ret = write(fd, value, strlen(value));
close(fd);
return (ret < 0) ? -1 : 0;
}
static long read_sysfs_long(const char *path)
{
FILE *fp = fopen(path, "r");
if (!fp) { perror(path); return -1; }
long val = 0;
fscanf(fp, "%ld", &val);
fclose(fp);
return val;
}
int dmc_lock_max(void)
{
long avail[16];
char buf[256];
int count = 0;
FILE *fp = fopen(DMC_AVAIL_FREQ, "r");
if (!fp) { perror("open available_frequencies"); return -1; }
while (count < 16 && fscanf(fp, "%ld", &avail[count]) == 1)
count++;
fclose(fp);
if (count == 0) { fprintf(stderr, "No available frequencies\n"); return -1; }
write_sysfs(DMC_GOVERNOR, "performance");
snprintf(buf, sizeof(buf), "%ld", avail[count - 1]);
write_sysfs(DMC_MAX_FREQ, buf);
write_sysfs(DMC_MIN_FREQ, buf);
long cur = read_sysfs_long(DMC_FREQ_PATH);
printf("DMC locked at %ld Hz\n", cur);
return 0;
}
int main(void)
{
long cur = read_sysfs_long(DMC_FREQ_PATH);
printf("RK3576 DMC - current: %ld Hz\n", cur);
dmc_lock_max();
return 0;
}编译运行:gcc -O2 -o dmc_ctrl dmc_ctrl.c && sudo ./dmc_ctrl
5.2 内存架构
┌──────────────────────────────────────────────────┐
│ Cortex-A72 / Cortex-A53 │
│ L1/ L2 Cache (片上缓存) │
├──────────────────────────────────────────────────┤
│ 片上互联 (NoC) │
├──────────────────────────────────────────────────┤
│ 内存控制器 (DMC) │
│ LPDDR5(标配 4GB) │
│ 具体通道/位宽与频率以 SDK 为准 │
└──────────────────────────────────────────────────┘5.3 内存泄漏监控脚本
#!/bin/bash
# mem-watchdog.sh — 监控内存使用并记录异常
LOG_DIR="/var/log/mem-watchdog"
LOG_FILE="$LOG_DIR/mem-$(date +%Y%m%d).log"
THRESHOLD=85
mkdir -p "$LOG_DIR"
while true; do
MEM_TOTAL=$(awk '/MemTotal/ {print $2}' /proc/meminfo)
MEM_AVAIL=$(awk '/MemAvailable/ {print $2}' /proc/meminfo)
MEM_PERCENT=$(( (MEM_TOTAL - MEM_AVAIL) * 100 / MEM_TOTAL ))
if [ "$MEM_PERCENT" -ge "$THRESHOLD" ]; then
echo "[$(date)] WARNING: ${MEM_PERCENT}% used" >> "$LOG_FILE"
ps aux --sort=-%mem | head -6 | tail -5 >> "$LOG_FILE"
fi
sleep 10
done6. 常见问题
Q1: DDR 频率无法提升到最高档
cat /sys/class/devfreq/dmc/governor # 确认为 performance
cat /sys/class/thermal/thermal_zone*/temp # 检查温度(温度过高会降频)
dmesg | grep -i "dmc\|devfreq\|ddr"Q2: M.2 SSD 未识别或速度低
lsblk # 确认设备是否存在
dmesg | grep -i "nvme\|pcie"
# 确认 M.2 插槽支持的 SSD 类型(NVMe/SATA)与底板原理图一致
# 确认 SSD 与系统协商的链路规格(待板上验证)Q3: zram 启用后系统卡顿
降低 zram 大小,切换 lz4 算法:
swapoff /dev/zram0
echo lz4 > /sys/block/zram0/comp_algorithm
echo $(( $(awk '/MemTotal/ {print $2}' /proc/meminfo) * 25 / 100 ))K > /sys/block/zram0/disksize
mkswap /dev/zram0 && swapon -p 100 /dev/zram0Q4: eMMC 长时间写入后速度下降
sudo mount -o remount,discard /
sudo fstrim -v /
sudo mmc extcsd read /dev/mmcblk0 | grep -i "life\|health"Q5: 内存泄漏进程排查
ps aux --sort=-%mem | head -5
valgrind --leak-check=full --show-leak-kinds=all ./suspect_binary
cat /proc/<PID>/smaps_rollupQ6: Huge Pages 分配失败
echo 0 | sudo tee /proc/sys/vm/nr_hugepages
echo 512 | sudo tee /proc/sys/vm/nr_hugepages
grep -i huge /proc/meminfoQ7: 4GB 内存下系统内存不足
# 启用 zram 压缩交换(见 4.7 节)
# 关闭不必要的系统服务(参考 ch01 系统启动时间优化)
# 使用 f2fs 压缩文件系统特性
free -h
cat /proc/meminfo | grep -E "MemTotal|MemAvailable|SwapTotal"7. 相关文档
| 文档名称 | 路径 | 说明 |
|---|---|---|
| 系统启动时间优化 | 系统启动时间优化 | 启动流程与系统级优化 |
| CPU-GPU-NPU 调优 | CPU-GPU-NPU调优 | 多核协同与频率调优 |
| 功耗分析与优化 | 功耗分析与优化 | 低功耗设计与功耗管理 |
| 调试工具使用指南 | 调试工具使用指南 | 常用调试与性能分析工具 |
| C/C++ 应用开发入门 | C/C++应用开发入门 | 编译环境与基础开发 |
| 文件系统与存储 | 文件系统与存储 | 存储分区和文件系统管理 |
| 硬件参考 | 硬件参考 | 核心板与底板硬件信息 |
