本人工作中遇到的实际问题,结合大模型分析后找到了原因
本文在CHATGPT帮助下完成
1. 问题背景
在使用 PyNvVideoCodec 做 GPU 视频解码测试时,发现一个非常奇怪的现象:
同一个视频:
第一次运行:
PyNvVideoCodec decode: 10s
第二次运行:
PyNvVideoCodec decode: 2s
代码、GPU、Docker 环境完全没有变化。
初步怀疑:
- PyNvVideoCodec 第一次初始化慢?
- NVDEC 有缓存?
- Qwen 模型加载影响?
- Docker 容器导致?
- GPU 驱动问题?
经过多组实验,最终定位:
真正影响性能的是 Linux Page Cache(文件缓存),而不是 GPU 解码本身。
2. Linux Page Cache 是什么?
Linux 不会每次读取文件都直接访问磁盘。
当程序读取文件:
程序
|
| read()
↓
Linux Kernel
|
↓
磁盘
第一次读取:
磁盘
↓
Page Cache
↓
程序
Linux 会把读取的数据缓存在内存中。
第二次读取:
程序
|
↓
Page Cache
|
↓
直接返回
不需要再次访问磁盘。
因此:
第一次:
磁盘 IO + 解码
第二次:
内存读取 + 解码
速度可能产生明显差异。
3. 为什么 Docker 重启后缓存还存在?
很多人会误以为:
Docker 容器退出后,缓存应该消失。
实际上不是。
Page Cache 属于:
Linux Kernel
不是:
Docker Container
例如:
第一次:
Docker A
读取 video.mp4
↓
Linux Page Cache
然后:
Docker A退出
但是:
Linux Kernel
仍然运行。
再次:
Docker B
读取同一个 video.mp4
仍然可以命中之前的 Page Cache。
所以:
不同 docker run 之间可以共享文件缓存。
4. 如何查看一个文件是否已经缓存?
推荐工具:
vmtouch
安装:
Ubuntu:
sudo apt install vmtouch
查看文件:
vmtouch video.mp4
输出:
Files: 1
Directories: 0
Resident Pages: 121973/121973 476M/476M 100%
Elapsed: 0.000458 seconds
Resident Pages 怎么理解?
Linux 使用 Page 管理内存。
通常:
1 Page = 4096 Bytes
例如:
视频:
476MB
大约:
476MB / 4KB
≈121973 Pages
输出:
Resident Pages:
121973 / 121973
表示:
总页数: 121973
已经在内存中的页: 121973
也就是:
100%
代表:
整个视频已经进入 Linux Page Cache。
如果:
Resident Pages:
50000 / 121973
40%
说明:
只有 40% 的视频数据已经缓存。
5. 查看目录缓存情况
查看整个目录:
vmtouch /data/videos
递归查看:
vmtouch -r /data/videos
例如:
Files: 100
Directories: 1
Resident Pages:
500000/800000 62%
表示:
目录下所有文件:
约 62% 已经在内存缓存。
6. 如何清理 Linux Page Cache?
性能测试时,经常需要模拟:
第一次访问文件(冷缓存)
可以使用:
方法一:清理整个系统缓存
执行:
sudo sh -c "sync && echo 3 > /proc/sys/vm/drop_caches"
解释:
sync
把脏数据写回磁盘:
RAM
↓
磁盘
避免数据丢失。
echo 3
含义:
1:
清理 Page Cache
2:
清理 inode/dentry cache
3:
两者都清理
一般测试使用:
3
清理后验证:
vmtouch video.mp4
应该:
之前:
Resident Pages:
121973/121973 100%
变成:
Resident Pages:
0/121973 0%
7. 更推荐:只清理指定文件缓存
如果只是测试某个视频,不建议清理整个系统缓存。
使用:
sudo vmtouch -e video.mp4
其中:
-e
=
evict
表示:
将该文件从 Page Cache 中移除。
验证:
vmtouch video.mp4
看到:
0%
即可。
8. 一个完整的视频解码测试流程
例如测试 PyNvVideoCodec:
第一步:清缓存
sudo vmtouch -e video.mp4
确认:
vmtouch video.mp4
结果:
0%
第二步:运行解码
第一次:
decoder[i]
10s
第三步:查看缓存
vmtouch video.mp4
结果:
100%
说明:
视频已经进入 Page Cache。
第四步:再次运行
第二次:
decoder[i]
2s
原因:
Page Cache命中
9. top/free 能看到这些缓存吗?
很多人会使用:
top
查看内存。
注意:
Page Cache 不属于某个进程。
所以:
top RES
不会包含文件缓存。
查看:
free -h
可以看到:
buff/cache
但这个包含:
- Page Cache
- inode cache
- slab 等
不是精确的文件缓存。
如果想知道:
某个视频是否缓存:
使用:
vmtouch
更准确。
10. 对视频处理系统的启示
对于视频分析任务:
例如:
NAS
|
复制
|
本地SSD
|
PyNvVideoCodec
|
Qwen
|
MediaPipe
推荐:
不要直接从网络文件系统做随机帧读取。
原因:
视频随机访问:
decoder[idx]
会频繁触发:
seek
read
decode
网络存储延迟会直接影响解码时间。
更稳定的架构:
NAS作为存储
↓
复制到本地SSD
↓
GPU解码
这样性能更加稳定,也方便测试。
总结
Linux Page Cache 是导致:
第一次读取慢
第二次读取快
的主要原因之一。
关键命令:
查看文件缓存:
vmtouch file
清理单个文件:
sudo vmtouch -e file
清理系统缓存:
sudo sh -c "sync && echo 3 > /proc/sys/vm/drop_caches"
对于视频解码性能测试,必须区分:
- 磁盘/NAS读取性能
- Page Cache命中
- GPU解码性能
否则容易误判:
“GPU解码慢”
实际上可能只是:
“第一次读取文件慢”。

436

被折叠的 条评论
为什么被折叠?



