389 lines
10 KiB
Markdown
389 lines
10 KiB
Markdown
# 性能调优指南
|
||
|
||
## 1. 系统优化
|
||
|
||
### 1.1 GPU设置
|
||
- 设置CUDA计算能力
|
||
- GPU功耗模式调整
|
||
- 显存预分配策略
|
||
|
||
### 1.2 系统配置
|
||
- CPU频率调节
|
||
- 系统IO优化
|
||
- 网络参数调整
|
||
|
||
## 2. Pipeline优化
|
||
|
||
### 2.1 多线程优化
|
||
- 线程池配置
|
||
- 任务调度策略
|
||
- 线程亲和性设置
|
||
|
||
### 2.2 内存优化
|
||
- 零拷贝传输
|
||
- 内存池管理
|
||
- 显存复用策略
|
||
|
||
### 2.3 批处理优化
|
||
- 动态批大小
|
||
- 批处理超时设置
|
||
- 帧积累策略
|
||
|
||
### 2.4 输入输出映射优化
|
||
- 映射关系管理
|
||
- 使用哈希表实现 O(1) 查找
|
||
- 缓存常用映射关系
|
||
- 避免频繁修改映射
|
||
- 并发访问优化
|
||
- 读写锁分离
|
||
- 细粒度锁定
|
||
- 避免长时间持锁
|
||
- 资源管理优化
|
||
- 智能指针管理生命周期
|
||
- 内存池复用
|
||
- 延迟初始化策略
|
||
|
||
## 3. 推理优化
|
||
|
||
### 3.1 TensorRT优化
|
||
- FP16/INT8量化
|
||
- 动态Shape处理
|
||
- Workspace大小设置
|
||
|
||
### 3.2 预处理优化
|
||
- GPU预处理
|
||
- 并行预处理
|
||
- 数据预取
|
||
|
||
## 4. IO优化
|
||
|
||
### 4.1 输入优化
|
||
- RTSP缓冲设置
|
||
- 解码器选择
|
||
- 帧采样策略
|
||
|
||
### 4.2 输出优化
|
||
- 编码器参数
|
||
- 推流缓冲
|
||
- 写入策略
|
||
|
||
### 4.3 映射关系优化
|
||
- 合理配置映射关系
|
||
- 避免不必要的多重映射
|
||
- 根据实际需求设置映射
|
||
- 定期清理无效映射
|
||
- 输出目标管理
|
||
- 复用输出目标
|
||
- 动态调整目标参数
|
||
- 按需初始化资源
|
||
- 性能监控
|
||
- 监控映射状态
|
||
- 跟踪资源使用
|
||
- 分析性能瓶颈
|
||
|
||
## 5. 监控与调试
|
||
|
||
### 5.1 性能指标
|
||
- GPU利用率
|
||
- 内存使用
|
||
- 处理延迟
|
||
- 吞吐量统计
|
||
|
||
### 5.2 性能分析
|
||
- NVPROF分析
|
||
- 内存泄漏检测
|
||
- 性能瓶颈定位
|
||
|
||
### 5.3 映射性能监控
|
||
- 映射关系统计
|
||
```cpp
|
||
// 获取映射统计信息
|
||
size_t total_sources = input_manager.getAllSourceNames().size();
|
||
size_t total_targets = output_manager.getTargetCount();
|
||
|
||
// 检查映射效率
|
||
for (const auto& source : input_manager.getAllSourceNames()) {
|
||
std::vector<std::string> targets;
|
||
input_manager.getOutputTargets(source, targets);
|
||
// 分析映射数量和资源使用
|
||
}
|
||
```
|
||
|
||
- 资源使用监控
|
||
```cpp
|
||
// 监控输出目标状态
|
||
for (const auto& target : output_manager.getTargetNames()) {
|
||
std::string error_msg;
|
||
bool status = output_manager.getTargetStatus(target, error_msg);
|
||
// 记录状态和错误信息
|
||
}
|
||
```
|
||
|
||
- 性能指标收集
|
||
```cpp
|
||
// 收集写入性能指标
|
||
struct PerformanceMetrics {
|
||
double avg_write_time;
|
||
double max_write_time;
|
||
size_t total_frames;
|
||
size_t dropped_frames;
|
||
};
|
||
|
||
// 定期更新和分析性能指标
|
||
void updateMetrics(const std::string& target, double write_time) {
|
||
metrics[target].avg_write_time =
|
||
(metrics[target].avg_write_time * metrics[target].total_frames + write_time) /
|
||
(metrics[target].total_frames + 1);
|
||
metrics[target].max_write_time = std::max(metrics[target].max_write_time, write_time);
|
||
metrics[target].total_frames++;
|
||
}
|
||
```
|
||
|
||
## 6. 映射性能优化建议
|
||
|
||
### 6.1 配置优化
|
||
|
||
1. 映射关系设计
|
||
- 避免创建不必要的映射
|
||
- 合理分组输出目标
|
||
- 根据实际需求配置映射
|
||
|
||
2. 缓冲区设置
|
||
- 为不同类型的输出配置适当的缓冲区
|
||
- 考虑输出目标的特性
|
||
- 平衡内存使用和性能
|
||
|
||
3. 参数调优
|
||
- 根据输出目标类型设置合适的参数
|
||
- 考虑网络条件和系统资源
|
||
- 动态调整参数以适应变化
|
||
|
||
### 6.2 代码优化
|
||
|
||
1. 映射查找优化
|
||
```cpp
|
||
// 使用哈希表存储映射关系
|
||
std::unordered_map<std::string, std::vector<std::string>> source_target_map;
|
||
|
||
// 缓存常用映射
|
||
std::unordered_map<std::string, std::vector<std::string>> mapping_cache;
|
||
|
||
// 快速查找实现
|
||
bool getTargets(const std::string& source, std::vector<std::string>& targets) {
|
||
auto it = mapping_cache.find(source);
|
||
if (it != mapping_cache.end()) {
|
||
targets = it->second;
|
||
return true;
|
||
}
|
||
|
||
auto map_it = source_target_map.find(source);
|
||
if (map_it != source_target_map.end()) {
|
||
targets = map_it->second;
|
||
mapping_cache[source] = targets;
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
```
|
||
|
||
2. 并发访问优化
|
||
```cpp
|
||
// 使用读写锁
|
||
mutable std::shared_mutex mapping_mutex;
|
||
|
||
// 读取映射关系
|
||
bool getTargets(const std::string& source, std::vector<std::string>& targets) const {
|
||
std::shared_lock<std::shared_mutex> lock(mapping_mutex);
|
||
auto it = source_target_map.find(source);
|
||
if (it != source_target_map.end()) {
|
||
targets = it->second;
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
// 更新映射关系
|
||
bool updateMapping(const std::string& source, const std::vector<std::string>& targets) {
|
||
std::unique_lock<std::shared_mutex> lock(mapping_mutex);
|
||
source_target_map[source] = targets;
|
||
mapping_cache.erase(source); // 清除缓存
|
||
return true;
|
||
}
|
||
```
|
||
|
||
3. 资源管理优化
|
||
```cpp
|
||
// 使用智能指针管理资源
|
||
class OutputTarget {
|
||
public:
|
||
using Ptr = std::shared_ptr<OutputTarget>;
|
||
static Ptr create(const OutputTargetConfig& config) {
|
||
return std::make_shared<OutputTarget>(config);
|
||
}
|
||
};
|
||
|
||
// 资源池管理
|
||
class ResourcePool {
|
||
public:
|
||
OutputTarget::Ptr acquireTarget(const std::string& name) {
|
||
std::lock_guard<std::mutex> lock(pool_mutex);
|
||
auto it = available_targets.find(name);
|
||
if (it != available_targets.end()) {
|
||
auto target = it->second;
|
||
available_targets.erase(it);
|
||
return target;
|
||
}
|
||
return nullptr;
|
||
}
|
||
|
||
void releaseTarget(const std::string& name, OutputTarget::Ptr target) {
|
||
std::lock_guard<std::mutex> lock(pool_mutex);
|
||
available_targets[name] = target;
|
||
}
|
||
|
||
private:
|
||
std::mutex pool_mutex;
|
||
std::unordered_map<std::string, OutputTarget::Ptr> available_targets;
|
||
};
|
||
```
|
||
|
||
### 6.3 性能监控
|
||
|
||
1. 映射效率监控
|
||
```cpp
|
||
struct MappingMetrics {
|
||
size_t mapping_updates;
|
||
size_t cache_hits;
|
||
size_t cache_misses;
|
||
double avg_lookup_time;
|
||
};
|
||
|
||
void updateMappingMetrics(const std::string& source, bool cache_hit, double lookup_time) {
|
||
auto& metrics = mapping_metrics[source];
|
||
metrics.mapping_updates++;
|
||
cache_hit ? metrics.cache_hits++ : metrics.cache_misses++;
|
||
metrics.avg_lookup_time =
|
||
(metrics.avg_lookup_time * (metrics.cache_hits + metrics.cache_misses - 1) + lookup_time) /
|
||
(metrics.cache_hits + metrics.cache_misses);
|
||
}
|
||
```
|
||
|
||
2. 资源使用监控
|
||
```cpp
|
||
struct ResourceMetrics {
|
||
size_t active_targets;
|
||
size_t total_memory;
|
||
size_t peak_memory;
|
||
double avg_utilization;
|
||
};
|
||
|
||
void updateResourceMetrics(const std::string& target, size_t memory_usage) {
|
||
auto& metrics = resource_metrics[target];
|
||
metrics.total_memory = memory_usage;
|
||
metrics.peak_memory = std::max(metrics.peak_memory, memory_usage);
|
||
// 更新其他指标...
|
||
}
|
||
```
|
||
|
||
### 6.4 常见问题解决
|
||
|
||
1. 映射性能问题
|
||
- 检查映射关系是否合理
|
||
- 优化缓存策略
|
||
- 调整锁粒度
|
||
|
||
2. 资源使用问题
|
||
- 监控内存使用
|
||
- 及时释放资源
|
||
- 优化资源池配置
|
||
|
||
3. 并发访问问题
|
||
- 使用适当的锁策略
|
||
- 减少锁的持有时间
|
||
- 考虑无锁实现
|
||
|
||
## RTSP 流读取优化
|
||
|
||
### 延迟与流畅度平衡
|
||
|
||
RTSP 流的读取性能主要受以下参数影响:
|
||
|
||
1. 缓冲区大小 (`buffer_size`)
|
||
- 较大的缓冲区可以提供更流畅的播放体验,但会增加延迟
|
||
- 较小的缓冲区可以降低延迟,但可能导致画面卡顿
|
||
- 建议值:
|
||
- 低延迟场景:5-10
|
||
- 一般场景:30
|
||
- 高流畅度场景:50-100
|
||
|
||
2. 帧率控制 (`target_fps`)
|
||
- 限制帧率可以减少系统资源占用
|
||
- 建议根据实际需求设置,通常不需要超过显示器刷新率
|
||
- 常见设置:
|
||
- 监控场景:15-20 fps
|
||
- 一般场景:25-30 fps
|
||
- 高帧率场景:60 fps
|
||
|
||
3. 超时设置 (`frame_timeout_ms`)
|
||
- 较短的超时时间可以更快地检测到连接问题
|
||
- 较长的超时时间可以容忍网络波动
|
||
- 建议值:
|
||
- 局域网:1000-2000 ms
|
||
- 互联网:3000-5000 ms
|
||
|
||
4. 重连策略
|
||
- `max_retry_count` 和 `retry_interval_ms` 的组合决定了重连行为
|
||
- 建议值:
|
||
- 稳定网络:重试 3 次,间隔 1000ms
|
||
- 不稳定网络:重试 5-10 次,间隔 2000-3000ms
|
||
|
||
### 优化建议
|
||
|
||
1. 网络优化
|
||
- 使用有线网络而不是无线网络
|
||
- 确保网络带宽充足
|
||
- 考虑使用 QoS 策略优先处理 RTSP 流量
|
||
|
||
2. 编码设置
|
||
- 使用 MJPEG 编码可以降低延迟
|
||
- H.264/H.265 编码可以节省带宽但会增加延迟
|
||
|
||
3. 分辨率与帧率
|
||
- 根据实际需求选择合适的分辨率和帧率
|
||
- 不要盲目追求高分辨率和高帧率
|
||
|
||
4. 内存管理
|
||
- 避免频繁的帧拷贝
|
||
- 考虑使用帧池来复用内存
|
||
|
||
### 性能监控
|
||
|
||
可以通过以下方式监控 RTSP 流的性能:
|
||
|
||
1. 帧率监控
|
||
```cpp
|
||
float current_fps = reader.getCurrentFps();
|
||
```
|
||
|
||
2. 连接状态监控
|
||
```cpp
|
||
bool is_connected = reader.isConnected();
|
||
```
|
||
|
||
### 常见问题解决
|
||
|
||
1. 画面卡顿
|
||
- 增加缓冲区大小
|
||
- 检查网络带宽
|
||
- 降低分辨率或帧率
|
||
|
||
2. 延迟过高
|
||
- 减小缓冲区大小
|
||
- 使用 MJPEG 编码
|
||
- 优化网络路径
|
||
|
||
3. 频繁断连
|
||
- 增加超时时间
|
||
- 调整重连策略
|
||
- 检查网络稳定性
|