了解OpenCV中OpenCL的用法(材质/单元对象)

Understanding the usage of OpenCL in OpenCV (Mat/ Umat Objects)

本文关键字:材质 单元 对象 用法 OpenCV OpenCL 了解      更新时间:2023-10-16

我运行下面的代码来检查GPU和CPU使用情况之间的性能差异。我正在计算cv::cvtColor()函数的平均时间。我调用了四个函数:

  1. Just_mat()(对于Mat对象不使用OpenCL)
  2. Just_UMat()(对于Umat对象不使用OpenCL)
  3. OpenCL_Mat()(对Mat对象使用OpenCL)
  4. OpenCL_UMat()(对UMat对象使用OpenCL)

用于CPU和GPU
我没有发现GPU和CPU使用之间存在巨大的性能差异。

int main(int argc, char* argv[])
{
loc = argv[1];
just_mat(loc);// Calling function Without OpenCL 
just_umat(loc);//Calling function Without OpenCL 
cv::ocl::Context context;
std::vector<cv::ocl::PlatformInfo> platforms;
cv::ocl::getPlatfomsInfo(platforms);
for (size_t i = 0; i < platforms.size(); i++)
{
//Access to Platform
const cv::ocl::PlatformInfo* platform = &platforms[i];
//Platform Name
std::cout << "Platform Name: " << platform->name().c_str() << "n" << endl;
//Access Device within Platform
cv::ocl::Device current_device;
for (int j = 0; j < platform->deviceNumber(); j++)
{
//Access Device
platform->getDevice(current_device, j);
int deviceType = current_device.type();
cout << "Device name:  " << current_device.name() << endl;
if (deviceType == 2)
cout << context.ndevices() << " CPU devices are detected." << std::endl;
if (deviceType == 4)
cout << context.ndevices() << " GPU devices are detected." << std::endl;
cout << "===============================================" << endl << endl;
switch (deviceType) 
{
case (1 << 1):
cout << "CPU devicen";
if (context.create(deviceType))
opencl_mat(loc);//With OpenCL Mat
break;
case (1 << 2):
cout << "GPU devicen";              
if (context.create(deviceType))
opencl_mat(loc);//With OpenCL UMat
break;
}
cin.ignore(1);
}
}
return 0;
}
int just_mat(string loc);// I check for the average time taken for cvtColor() without using OpenCl
int just_umat(string loc);// I check for the average time taken for cvtColor() without using OpenCl
int opencl_mat(string loc);//ocl::setUseOpenCL(true); and check for time difference for cvtColor function
int opencl_umat(string loc);//ocl::setUseOpenCL(true); and check for time difference for cvtColor function

上述代码的输出(以毫秒为单位)为
__________________________________________
|GPU名称|带OpenCL Mat |带OpenCL UMat |
| _________________________________________ |
|--Carrizo---|--------7.69052-------0.247069-----|
>|_________________________________________ |
|--Island---|--------71.124555-------0.233345-----|
|_________________________________________ |


_________________________________________
|----CPU---|带OpenCL Mat |带OpenCL UMat |
|1________________________________________ |
|----AMD---|---------6.76169-|---------0.231103-|
>|________________________________________ |


_______________________________________________
|----CPU---|WithOut OpenCL Mat|WithOut Open Cl UMat|
|1_______________________________________________ |
|----AMD---|-------7.15959------|--------------0.246138------|
>|_______________________________________________ |

在代码中,使用Mat对象总是在CPU&使用UMat对象始终在GPU上运行,与代码ocl::setUseOpenCL(true/false);无关
有人能解释所有输出时间变化的原因吗

还有一个问题,我没有将任何OpenCL特定的.dll与.exe文件一起使用,但GPU在使用Cmake构建OpenCV时没有任何错误,我检查了With_OpenCL,这是否在opencv_World310.dll中构建了所有OpenCL所需的功能?

在代码中,使用Mat对象总是在CPU&使用UMat对象始终在GPU上运行,与代码ocl::setUseOpenCL无关(true/false);

很抱歉,因为我不确定这是一个问题还是一个声明。。。无论哪种情况,都有一部分是真的。在3.0中,对于UMat,如果你没有专用的GPU,那么OpenCV只是在CPU上运行所有东西。如果你特别要求Mat,你会在CPU上得到它。在你的情况下,你已经指示两者都在你的每个GPU/CPU上运行,具体选择每一个(更多关于"选择下面的CPU")…阅读:

很少有设计选择支持新架构:

  1. 一个统一的抽象cv::UMat,它允许使用CPU或OpenCL代码实现相同的API,而不需要调用OpenCL显式加速版本。这些函数使用OpenCL-启用GPU(如果系统中存在),并自动切换到CPU否则操作。

  2. UMat抽象使函数能够异步调用。与OpenCV 2.x版本的cv::Mat不同,访问underlyicv::UMat的ng数据是通过类的方法执行的,而不是通过其数据成员执行的。这种方法使只有当CPU代码绝对需要结果时,才显式等待GPU完成。

  3. UMat实现利用了Intel SoC上可用的CPU-GPU共享物理内存,包括来自传递到OpenCV的指针的分配。

我认为对于"使用OpenCL"也可能存在误解。当您使用UMat时,您特别想使用GPU。而且,我在这里为一些无知辩护,因此我相信CV正在使用CL库中的一些来自动实现这一点。。。作为2.X中的一方,我们有cv::ocl来专门/手动地完成这项工作,所以如果您在3.X中使用2.X遗留代码,请小心。这样做是有原因的,但并不总是简单的。但是,回到主题上,当你说

使用OpenCL UMat

您可能是多余的。你的代码片段中的CL代码基本上是找出安装了什么设备,有多少,它们的名称是什么,并选择使用哪个。。。我必须仔细研究它的实例化方式,但也许当你使它成为UMat时,它会自动将OpenCL设置为True?(链接)这肯定会支持你提供的数据。在将ocl::setUseOpenCL设置为false并使用UMat之后,您可以通过检查它的状态来测试这个想法。

最后,我猜你的CPU有一个内置的GPU。因此,它使用OpenCL运行并行处理,并且不需要支付往返于单独/专用GPU的时间代价,因此您可以感知到GPU的性能提高(因为从技术上讲,它不是运行它的CPU)。。。只有当您专门使用Mat时,才使用CPU。

你的最后一个问题,我不确定。。。这是我的猜测:GPU上存在OpenCL architexture,当你用CL安装CV时,你就是在安装两个库和相关头文件之间的链接。我不确定你需要哪些dll文件才能实现这种神奇的效果。