一文彻底搞懂为什么OpenCV用GPU/cuda跑得比用CPU慢?

您所在的位置:网站首页 跑代码吃cpu还是显卡还是内存 一文彻底搞懂为什么OpenCV用GPU/cuda跑得比用CPU慢?

一文彻底搞懂为什么OpenCV用GPU/cuda跑得比用CPU慢?

2024-07-13 13:32| 来源: 网络整理| 查看: 265

一、原因总结

最近项目需要,发现了这个问题。网上找原因,汇总起来,有以下几点原因:

1、首先对于任何一个CUDA程序,在调用它的第一个CUDA API时后都要花费秒级的时间去初始化运行环境,后续还要分配显存,传输数据,启动内核,每一样都有延迟。这样如果你一个任务CPU运算都仅要几十毫秒,相比而言必须带上这些延迟的GPU程序就会显得非常慢。

2、其次,一个运算量很小的程序,你的CUDA内核不可能启动太多的线程,没有足够的线程来屏蔽算法执行时从显存加载数据到GPU SM中的时延,这就没有发挥GPU的真正功能。

3、数据从内存传递到显存和cudaMalloc耗时很长,NVIDIA提供的nsight中的profile可以看每一个部分的耗时。基本上OpenCV的算法都归纳为三个部分:upload(gpu::Mat), processCodeBlock, download(gpu::Mat)。你看看是不是80%以上的时间都花在第一个和最后一个上,问题就迎刃而解了。因为gpu在计算上虽然比cpu快,但实际上在使用gpu的时候有一步非常耗时,那就是将内存与显存中的数据进行互相拷贝,同时这也是使用gpu运算时逃不掉的一步。

4、GPU擅长的是大规模并行计算,比起cpu只是以巨额核心数取得优势的,单核速度其实被cpu碾压。如果数据规模小的话GPU并不能用上太多核,所以比cpu慢。减少数据在CPU和GPU之间的传递次数;运算量非常小的部分不要用GPU,数据量非常大、循环次数非常多的时候才使用GPU。

//执行这些简单算子,CPU比GPU更快

cvtColor,GaussianBlur,Canny

//执行这些耗时算子,GPU比CPU更快

HoughCircles,HoughLines,matchTemplate

5、如果问题规模较小,逻辑控制较为复杂,并行性很小优先使用CPU处理该问题,如果包含较大规模的数据处理,则考虑使用GPU进行处理。

CPU上线程是重量级实体,可以开启1~32个线程,且上下文切换较为缓慢,GPU上线程是高度轻量级的,可以开几百甚至上千个线程。

CUDA通过两种API来对设备GPU设备进行控制,包括驱动API和运行API,其中驱动API较难编程,但是设备控制能力和利用率高。两者只能选择其中一种,不能混合使用。

一个CUDA程序包含了两个部分代码,在CPU上运行的主机代码和在GPU上运行的设备代码。

6、总结一句,GPU的并行处理的确很快,但数据传入GPU和传出的开销实在太大,往往影响了代码的整体效率,运算量非常小的计算不要用GPU。

二、举例opencv #include #include #include #include #include #include #include #include #include #include #include #define IMAGE_TEST_PATHNAME "D:\\test_src.jpg" #define IMAGE_SOURCE "D:\\test_src.jpg" #define IMAGE_TEMPLATE "D:\\test_templ.jpg" void checkCuda() //旧版本的是cv::gpu,#include ,已弃用 { int64 begintime, endtime; int num_devices = cv::cuda::getCudaEnabledDeviceCount(); if (num_devices


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3