Add DDR tooling and reduce RGA inference copies

This commit is contained in:
tian 2026-03-14 16:44:43 +08:00
parent 3b778b70dd
commit 7d5bec8040
8 changed files with 198 additions and 7 deletions

View File

@ -40,6 +40,7 @@
"use_rga": true,
"rga_gate": "person_shoe_two_stage",
"rga_max_inflight": 4,
"dst_packed": true,
"infer_fps": 2,
"model_path": "./models/yolov8n-640.rknn",
"model_version": "v8",
@ -80,6 +81,7 @@
"use_rga": true,
"rga_gate": "person_shoe_two_stage",
"rga_max_inflight": 4,
"dst_packed": true,
"infer_fps": 1,
"model_path": "./models/shoe_detector_openimages_ppe_v1.rknn",
"model_w": 640,

View File

@ -40,6 +40,7 @@
"use_rga": true,
"rga_gate": "person_shoe_two_stage_balanced",
"rga_max_inflight": 4,
"dst_packed": true,
"infer_fps": 2,
"model_path": "./models/yolov8n-640.rknn",
"model_version": "v8",
@ -80,6 +81,7 @@
"use_rga": true,
"rga_gate": "person_shoe_two_stage_balanced",
"rga_max_inflight": 4,
"dst_packed": true,
"infer_fps": 2,
"model_path": "./models/shoe_detector_openimages_ppe_v1.rknn",
"model_w": 640,

View File

@ -40,6 +40,7 @@
"use_rga": true,
"rga_gate": "person_shoe_two_stage_recall",
"rga_max_inflight": 4,
"dst_packed": true,
"infer_fps": 3,
"model_path": "./models/yolov8n-640.rknn",
"model_version": "v8",
@ -80,6 +81,7 @@
"use_rga": true,
"rga_gate": "person_shoe_two_stage_recall",
"rga_max_inflight": 4,
"dst_packed": true,
"infer_fps": 2,
"model_path": "./models/shoe_detector_openimages_ppe_v1.rknn",
"model_w": 640,

View File

@ -123,6 +123,32 @@ sudo ./scripts/deploy.sh install
sudo ./scripts/deploy.sh status
```
### 3.1 DDR 固频排障
当出现 `CPU/NPU` 利用率不高,但 RTSP 输出帧率周期性跌落时,优先检查 DDR devfreq 是否在频繁降频。
项目内置了 DDR 模式切换脚本:
```bash
sudo bash ./scripts/ddr_mode.sh status
sudo bash ./scripts/ddr_mode.sh performance
sudo bash ./scripts/ddr_mode.sh restore
```
也可以从运维入口调用:
```bash
sudo ./scripts/ops.sh ddr-status
sudo ./scripts/ops.sh ddr-performance
sudo ./scripts/ops.sh ddr-restore
```
说明:
- `performance`:保存当前 governor/min/max 后,将 DDR 切到高性能模式
- `restore`:恢复到切换前保存的 governor/min/max
- 默认节点为 `/sys/class/devfreq/dmc`
### 4. 卸载
```bash

View File

@ -571,6 +571,7 @@ private:
const uint8_t* model_input_data = nullptr;
size_t model_input_size = 0;
int model_input_dma_fd = -1;
if (image_processor_ && win_w > 0 && win_h > 0) {
Frame crop_frame;
@ -595,7 +596,11 @@ private:
? resized_frame.planes[0].stride
: (resized_frame.stride > 0 ? resized_frame.stride : model_w_ * 3);
const size_t packed_size = static_cast<size_t>(model_w_) * static_cast<size_t>(model_h_) * 3;
if (resized_data && resized_stride > 0) {
if (resized_frame.DmaFd() >= 0 && resized_data) {
model_input_data = resized_data;
model_input_size = resized_frame.data_size > 0 ? resized_frame.data_size : packed_size;
model_input_dma_fd = resized_frame.DmaFd();
} else if (resized_data && resized_stride > 0) {
if (packed_size > input_buf_.size()) input_buf_.resize(packed_size);
for (int row = 0; row < model_h_; ++row) {
memcpy(input_buf_.data() + static_cast<size_t>(row) * static_cast<size_t>(model_w_) * 3,
@ -622,6 +627,7 @@ private:
input.is_nhwc = true;
input.data = model_input_data;
input.size = model_input_size;
input.dma_fd = model_input_dma_fd;
input.type = RKNN_TENSOR_UINT8;
auto r = infer_backend_->InferBorrowed(model_handle_, input);

View File

@ -929,31 +929,50 @@ private:
const int resized_stride = resized_frame.planes[0].stride > 0
? resized_frame.planes[0].stride
: (resized_frame.stride > 0 ? resized_frame.stride : static_cast<int>(input_row));
if (resized_data && resized_stride > 0) {
if (resized_frame.DmaFd() >= 0 && resized_data) {
input.data = resized_data;
input.size = resized_frame.data_size > 0 ? resized_frame.data_size : input_size;
input.width = model_input_w_;
input.height = model_input_h_;
input.dma_fd = resized_frame.DmaFd();
input.dma_offset = 0;
} else if (resized_data && resized_stride > 0) {
for (int y = 0; y < model_input_h_; ++y) {
memcpy(resized_input_.data() + static_cast<size_t>(y) * input_row,
resized_data + static_cast<size_t>(y) * static_cast<size_t>(resized_stride),
input_row);
}
input.data = resized_input_.data();
input.size = input_size;
input.width = model_input_w_;
input.height = model_input_h_;
} else {
ResizeRgbBilinear(src, w, h, src_stride,
resized_input_.data(), model_input_w_, model_input_h_,
static_cast<int>(input_row));
input.data = resized_input_.data();
input.size = input_size;
input.width = model_input_w_;
input.height = model_input_h_;
}
} else {
ResizeRgbBilinear(src, w, h, src_stride,
resized_input_.data(), model_input_w_, model_input_h_,
static_cast<int>(input_row));
input.data = resized_input_.data();
input.size = input_size;
input.width = model_input_w_;
input.height = model_input_h_;
}
} else {
ResizeRgbBilinear(src, w, h, src_stride,
resized_input_.data(), model_input_w_, model_input_h_,
static_cast<int>(input_row));
input.data = resized_input_.data();
input.size = input_size;
input.width = model_input_w_;
input.height = model_input_h_;
}
input.data = resized_input_.data();
input.size = input_size;
input.width = model_input_w_;
input.height = model_input_h_;
}
input.is_nhwc = true;

102
scripts/ddr_mode.sh Normal file
View File

@ -0,0 +1,102 @@
#!/bin/bash
set -euo pipefail
DEV=${DDR_DEV:-/sys/class/devfreq/dmc}
STATE_DIR=${DDR_STATE_DIR:-/tmp/orangepi-ddr-mode}
usage() {
cat <<'EOF'
Usage:
sudo ./scripts/ddr_mode.sh status
sudo ./scripts/ddr_mode.sh performance
sudo ./scripts/ddr_mode.sh ondemand
sudo ./scripts/ddr_mode.sh restore
EOF
}
require_dev() {
if [[ ! -d "$DEV" ]]; then
echo "DDR devfreq node not found: $DEV" >&2
exit 1
fi
}
show_status() {
require_dev
echo "DDR devfreq node: $DEV"
[[ -f "$DEV/name" ]] && echo "name: $(cat "$DEV/name")"
[[ -f "$DEV/governor" ]] && echo "governor: $(cat "$DEV/governor")"
[[ -f "$DEV/available_governors" ]] && echo "available_governors: $(cat "$DEV/available_governors")"
[[ -f "$DEV/min_freq" ]] && echo "min_freq: $(cat "$DEV/min_freq")"
[[ -f "$DEV/max_freq" ]] && echo "max_freq: $(cat "$DEV/max_freq")"
[[ -f "$DEV/cur_freq" ]] && echo "cur_freq: $(cat "$DEV/cur_freq")"
[[ -f "$DEV/available_frequencies" ]] && echo "available_frequencies: $(cat "$DEV/available_frequencies")"
}
save_state() {
mkdir -p "$STATE_DIR"
[[ -f "$DEV/governor" ]] && cat "$DEV/governor" > "$STATE_DIR/governor"
[[ -f "$DEV/min_freq" ]] && cat "$DEV/min_freq" > "$STATE_DIR/min_freq"
[[ -f "$DEV/max_freq" ]] && cat "$DEV/max_freq" > "$STATE_DIR/max_freq"
}
set_performance() {
require_dev
save_state
if [[ -f "$DEV/available_governors" ]] && grep -qw performance "$DEV/available_governors"; then
echo performance > "$DEV/governor"
elif [[ -f "$DEV/available_frequencies" ]]; then
max=$(tr ' ' '\n' < "$DEV/available_frequencies" | sort -n | tail -n1)
echo "$max" > "$DEV/min_freq"
echo "$max" > "$DEV/max_freq"
else
echo "No performance governor or available_frequencies for $DEV" >&2
exit 1
fi
show_status
}
set_ondemand() {
require_dev
if [[ -f "$DEV/available_governors" ]] && grep -qw dmc_ondemand "$DEV/available_governors"; then
echo dmc_ondemand > "$DEV/governor"
else
echo "dmc_ondemand governor not available for $DEV" >&2
exit 1
fi
show_status
}
restore_state() {
require_dev
if [[ ! -d "$STATE_DIR" ]]; then
echo "No saved DDR state found in $STATE_DIR" >&2
exit 1
fi
[[ -f "$STATE_DIR/governor" ]] && cat "$STATE_DIR/governor" > "$DEV/governor"
[[ -f "$STATE_DIR/min_freq" ]] && cat "$STATE_DIR/min_freq" > "$DEV/min_freq"
[[ -f "$STATE_DIR/max_freq" ]] && cat "$STATE_DIR/max_freq" > "$DEV/max_freq"
show_status
}
case "${1:-status}" in
status)
show_status
;;
performance)
set_performance
;;
ondemand)
set_ondemand
;;
restore)
restore_state
;;
-h|--help|help)
usage
;;
*)
usage
exit 1
;;
esac

View File

@ -2,7 +2,7 @@
# RK3588 Media Server 运维脚本
# 安装后位于 /opt/rk3588-media-server/script/ops.sh
#
# 用法: sudo ./ops.sh [status|start|stop|restart|logs|hw]
# 用法: sudo ./ops.sh [status|start|stop|restart|logs|hw|ddr-status|ddr-performance|ddr-ondemand|ddr-restore]
set -e
@ -118,6 +118,22 @@ cmd_metrics() {
/opt/rk3588-media-server/scripts/monitor_hw.sh
}
cmd_ddr_status() {
bash /opt/rk3588-media-server/scripts/ddr_mode.sh status
}
cmd_ddr_performance() {
bash /opt/rk3588-media-server/scripts/ddr_mode.sh performance
}
cmd_ddr_ondemand() {
bash /opt/rk3588-media-server/scripts/ddr_mode.sh ondemand
}
cmd_ddr_restore() {
bash /opt/rk3588-media-server/scripts/ddr_mode.sh restore
}
# 主入口
case "${1:-status}" in
status)
@ -138,6 +154,18 @@ case "${1:-status}" in
hw)
cmd_metrics
;;
ddr-status)
cmd_ddr_status
;;
ddr-performance)
cmd_ddr_performance
;;
ddr-ondemand)
cmd_ddr_ondemand
;;
ddr-restore)
cmd_ddr_restore
;;
*)
echo "RK3588 Media Server 运维脚本"
echo ""
@ -150,6 +178,10 @@ case "${1:-status}" in
echo " restart 重启服务"
echo " logs 查看实时日志"
echo " hw 查看硬件监控"
echo " ddr-status 查看 DDR 频率策略"
echo " ddr-performance DDR 切到高性能模式"
echo " ddr-ondemand DDR 切回 dmc_ondemand"
echo " ddr-restore 恢复上次保存的 DDR 配置"
echo ""
echo "示例:"
echo " sudo $(basename $0) status"