Linux Page Cache 导致视频解码第一次慢、第二次快的原因分析与缓存清理方法

本人工作中遇到的实际问题,结合大模型分析后找到了原因
本文在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解码慢”

实际上可能只是:

“第一次读取文件慢”。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Garfield2005

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值