【C++】【TensorRT】检测时间不稳定原因汇总(持续更新)

本人使用C++版本的TensorRT框架做模型部署的开发工作,在实际上线具体的项目过程中碰到过检测时间不理想的情况,所以本人专门为此写一篇博客记录曾经遇到过的坑以及对应的解决方案。

一、相同型号的机器和显卡检测时间不同

1.问题描述

两台相同型号的机器、相同型号的显卡,在做分割项目时检测结果都一样,但是检测速度却不同。

2.问题查询

将每个模块的耗时打印出来,来观察哪一个模块耗时不相同,本人分成了以下5个部分:
a.前处理
vector< cv::Mat >—>float *
b.数据送内存到显存

cudaMemcpyAsync(mBinding[bindIndex], input, mBindingSize[bindIndex], cudaMemcpyHostToDevice, stream)

c.前向传播(调用 executeV2 (bindings))

mContext->enqueueV2(&mBinding[0], stream, nullptr);

d.数据从显存到内存

cudaMemcpyAsync(output.data(), mBinding[bindIndex], mBindingSize[bindIndex], cudaMemcpyDeviceToHost, stream);

e.后处理
vector< float > —>vector< cv::Mat >

3.实验结果

最终发现在数据从显存到内存传输的过程中,时间是不相同的。
(cudaMemcpyAsync in cudaMemcpyDeviceToHost mode)

4.可能原因

经过本人一番搜索后,了解到有个设置会干扰这部分时间,就是分页内存
长话短说就是设置无分页内存可以让速度达到最快,而设置虚拟内存会导致速度变慢

5.解决方案

对系统设置无分页内存
具体操作:
a.搜索栏搜索 高级系统设置
【C++】【TensorRT】检测时间不稳定原因汇总(持续更新)_第1张图片

b.点击性能中的设置
【C++】【TensorRT】检测时间不稳定原因汇总(持续更新)_第2张图片
c.点击高级中的更改
【C++】【TensorRT】检测时间不稳定原因汇总(持续更新)_第3张图片
d.点击 无分页文件 再点击右边的设置
【C++】【TensorRT】检测时间不稳定原因汇总(持续更新)_第4张图片
e.最后点确定然后重启计算机即可。

二、部分机器上检测时间波动较大

1.问题描述

部分机器上检测时间会非常不稳定,比如理论上应该是30ms一张图,但是隔几张之后就变成100ms以上,然后又变成30ms。但是同一套程序在部分的机器上又是稳定的,所以排除了代码问题。
而且除了TensorRT框架外,本人使用Libtorch框架做的检测项目也发生了类似的情况,所以或许问题点不在TensorRT本身。

2.问题查询

仍然按照上述问题一的思路。

3.实验结果

仍然是数据从显存到内存的时间不稳定所导致的。
(cudaMemcpyAsync in cudaMemcpyDeviceToHost mode is slow)
PS:到这里可以得出个大概规律,TensorRT的耗时有问题很有可能是数据从显存到内存这个地方导致的。

4.可能原因

经过了本人地毯式的搜索,并没有找到与本人相同的问题以及解决方案。
本人只能根据手上有的机器以及显卡来猜测究竟是哪个因素导致检测时间有较大波动。
本人猜测了显卡型号、精度模式(FP16 or FP32)、CPU型号、CPU核心数等等因素,都被否决了。
最后本人发现一个很神奇的点,那就是检测时间稳定的机器上显卡驱动版本都是500以下的,而检测时间不稳定的机器上显卡驱动版本都是500以上的,于是乎本人试了下将显卡驱动为512的一台机器显卡驱动降级到472.84版本,没想到检测时间变稳定了!
当时第一反应就觉得是这个版本问题。但是本人下载的这个驱动是通过驱动精灵下载的,不是DCH版本,而是标准版本。本人又猜想莫非是DCH和标准的区别而导致的?
于是本人又下载了个DCH版本的472.84的显卡驱动,安装完后发现时间仍然是稳定的。
到这里基本可以断言,数据从显存传到内存这一环节与显卡驱动版本是有关系的!至少本人这里400~500的版本是没问题,而512版本的驱动会导致速度不稳定!

5.解决方案

直接将512版本的显卡驱动降级,降到470左右的版本。
具体操作:(建议按照本人操作来,因为会有坑)
a.首先搜索栏搜索设备管理器

b.点击显示适配器,底下应该有个属于自己机器的显卡,右键点击它,然后点击卸载设备,再卸载驱动,接着重启电脑。
【C++】【TensorRT】检测时间不稳定原因汇总(持续更新)_第5张图片

c.重启电脑之后先看下还有没有英伟达控制面板,有的话看看有没有降级到4XX的版本,如果有的话,就直接试试看应该可以稳定检测了。
如果连英伟达控制面板都没有的话,就下载驱动精灵,然后它会提示更新驱动,此时显示的是一个472.82的标准版驱动。点击它让它更新。(截图中箭头的地方一开始是升级驱动,点击它)
本人将这个版本的驱动放到了阿里云盘,也可以直接通过下面本人的阿里云盘链接直接下载
https://www.aliyundrive.com/s/oE8TvmKAw4t
提取码:25fn
【C++】【TensorRT】检测时间不稳定原因汇总(持续更新)_第6张图片

Tip:
如果这一步直接使用的是NVIDIA官网的DCH驱动的话,安装的时候会报错。

d.更新完驱动后再次打开程序,这个时候程序检测时间就变得稳定了。

6.展望

当然由于本人在编译TensorRT环境的时候,显卡驱动是472.88版本,所以与显卡驱动512版本会有不兼容的情况。
下一步本人打算在显卡驱动为512版本的机器上重新编译,然后再试一下能否稳定运行,后续会更新实验结果。

2022.09.26更新:
本人在512版本的显卡驱动上重新编译和测试,时间仍然是不稳定的。而且
所以基本可以得出结论:
显卡驱动版本在500以上的会导致TensorRT推理时间不稳定,建议换成500以下的。

本人在NVIDIA官网上提交此问题,目前正在等待NVIDIA官网的回复。
The time of cudaMemcpyAsync() in cudaMemcpyDeviceToHost mode is unstable after upgrading the graphics card driver to version 512

2022.09.28更新:
本人在类似的一篇帖子中发现推理时间变慢跟GPU时钟频率有关系,所以本人试着将GPU频率给锁死,结果是速度变稳定了,而且甚至比原来快了3ms左右
如果本人输入的是最高频率,那么就会很稳定,但是如果输入的不是最高频率,仍然会间隔10几张图之后有跳动。
将GPU时钟频率锁死的具体操作:
用管理员的方式打开cmd(不用管理员的方式后面可能会报错),然后输入nvidia-smi -q -d SUPPORTED_CLOCKS,看最大的时钟频率是多少,比如本人的结果如下图所示。【C++】【TensorRT】检测时间不稳定原因汇总(持续更新)_第7张图片
接着输入nvidia-smi -lgc 7501,成功后会有如下的提示。
请添加图片描述
问题来了,如果本人输入的不是7501,比如输入7001的话,仍然会间隔十几张图后不太稳定,如下图所示:
【C++】【TensorRT】检测时间不稳定原因汇总(持续更新)_第8张图片
参考资料:
深度学习显卡驱动设置?

2022.10.06更新:
NVIDIA官方给出了回复,如下图所示。
【C++】【TensorRT】检测时间不稳定原因汇总(持续更新)_第9张图片
翻译过来就是
1.不用分页内存,使用固定内存
2.设置时钟频率为最高频率
两个做法我都有做过,但是并没有给出正面的回答(为什么跟显卡驱动版本有关)。

你可能感兴趣的:(C++,TensorRT,深度学习,c++,深度学习,计算机视觉)