了解OpenCV中OpenCL的用法(Mat / Umat对象) [英] Understanding the usage of OpenCL in OpenCV (Mat/ Umat Objects)

查看:2361
本文介绍了了解OpenCV中OpenCL的用法(Mat / Umat对象)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I ran the code below to check for the performance difference between GPU and CPU usage. I am calculating the Average time for cv::cvtColor() function. I make four function calls:


  1. Just_mat()(不使用OpenCL for Mat object)

  2. Just_UMat()(不使用OpenCL for Umat object)

  3. OpenCL_Mat()(使用OpenCL for Mat object)

  4. OpenCL_UMat()(使用OpenCL for UMat 对象)

  1. Just_mat()(Without using OpenCL for Mat object)
  2. Just_UMat()(Without using OpenCL for Umat object)
  3. OpenCL_Mat()(using OpenCL for Mat object)
  4. OpenCL_UMat() (using OpenCL for UMat object)



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

for both CPU and GPU.
I did not find a huge performance difference between GPU and CPU usage.

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 device\n";
                if (context.create(deviceType))
                    opencl_mat(loc);//With OpenCL Mat
                break;
            case (1 << 2):
                cout << "GPU device\n";              
                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 ------- |

| _________________________________________ |

| ---岛--- | ------- 7.12455 ------ | - ----- 0.233345 ------- |

| _________________________________________ |

The output(in miliseconds) for the above code is
__________________________________________
|GPU Name|With OpenCL Mat | With OpenCl UMat|
|_________________________________________|
|--Carrizo---|------7.69052 ------ |------0.247069-------|
|_________________________________________|
|---Island--- |-------7.12455------ |------0.233345-------|
|_________________________________________|


__________________________________________
b $ b | ---- CPU --- |使用OpenCL Mat |使用OpenCl UMat |

| _________________________________________ |

| --- AMD --- | ------ 6.76169 ------ | ------ --0.231103 -------- |

| _________________________________________ |


__________________________________________
|----CPU---|With OpenCL Mat | With OpenCl UMat |
|_________________________________________|
|---AMD---|------6.76169 ------ |--------0.231103--------|
|_________________________________________|


________________________________________________

| ---- CPU --- | WithOut OpenCL Mat | WithOut OpenCl UMat |

| _______________________________________________ |

| ---- AMD --- | ------ 7.15959 ------ | ----- ------- 0.246138 ------------ |

| _______________________________________________ |


________________________________________________
|----CPU---| WithOut OpenCL Mat | WithOut OpenCl UMat |
|_______________________________________________|
|----AMD---|------7.15959------ |------------0.246138------------ |
|_______________________________________________|

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


任何人都可以解释所有输出时间变化的原因是什么?


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

In code, using Mat Object always runs on CPU & using UMat Object always runs on GPU, irrespective of the code ocl::setUseOpenCL(true/false);
Can anybody explain the reason for all output time variation?

One more question, i didn't use any OpenCL specific .dll with .exe file and yet GPU was used without any error, while building OpenCV with Cmake i checked With_OpenCL did this built all OpenCL required function within opencv_World310.dll ?

推荐答案


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

In code, using Mat Object always runs on CPU & using UMat Object always runs on GPU, irrespective of the code ocl::setUseOpenCL(true/false);

对不起,因为我不确定这是一个问题还是一个陈述......无论哪种情况都是如此。在3.0中,对于 UMat ,如果您没有专用GPU,那么OpenCV只会运行CPU上的所有内容。如果你特别要求 Mat ,你可以在CPU上获得它。在你的情况下,你通过选择每个GPU / CPU指导两者都运行(更多关于选择下面的CPU)...阅读这个

I'm sorry, because I'm not sure if this is a question or a statement... in either case it's partially true. In 3.0, for the UMat, if you don't have a dedicated GPU then OpenCV just runs everything on the CPU. If you specifically ask for Mat you get it on the CPU. And in your case you have directed both to run on each of your GPUs/CPU by selecting each specifically (more on "choosing a CPU below)... read this:


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

Few design choices support the new architecture:


  1. 统一抽象cv :: UMat,可以实现相同的API使用CPU或OpenCL代码,无需明确调用
    OpenCL加速版本。如果存在于系统中,这些函数使用OpenCL
    -enabled GPU,否则自动切换到CPU
    操作。

  1. A unified abstraction cv::UMat that enables the same APIs to be implemented using CPU or OpenCL code, without a requirement to call OpenCL accelerated version explicitly. These functions use an OpenCL -enabled GPU if exists in the system, and automatically switch to CPU operation otherwise.

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

The UMat abstraction enables functions to be called asynchronously. Unlike the cv::Mat of the OpenCV version 2.x, access to the underlyi ng data for the cv::UMat is performed through a method of class, and not though its data member. Such an approach enables the implementation to explicitly wait for GPU completion only when CPU code absolutely needs the result.

UMat实现利用CPU-GPU英特尔SoC上可用的共享物理内存,包括来自传递给OpenCV的指针的分配。

The UMat implementation makes use of CPU-GPU shared physical memory available on Intel SoCs, including allocations that come from pointers passed into OpenCV.


我认为也可能存在对使用OpenCL的误解。当您使用 UMat 时,您特意尝试使用GPU。而且,我会在这里恳求一些无知,因此我相信CV正在使用一些CL库来自动发生...作为2.X中的一方我们有cv :: ocl来专门/手动执行这个,所以在3.X中使用2.X遗留代码时要小心。有理由这样做,但它们并不总是直截了当。但是,回到主题,当你说,

I think there also might be a misunderstanding about "using OpenCL". When you use an UMat, you are specifically trying to use the GPU. And, I'll plead some ignorance here, as a result I believe that CV is using some of the CL library to make that happen automatically... as a side in 2.X we had cv::ocl to specifically/manually do this, so be careful if you are using that 2.X legacy code in 3.X. There are reasons to do it, but they are not always straightforward. But, back on topic, when you say,


使用OpenCL UMat

with OpenCL UMat

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

you are potentially being redundant. The CL code you have in your snippet is basically finding out what equipment is installed, how many there are, what their names are, and choosing which to use... I'd have to dig through the way it is instantiated, but perhaps when you make it UMat it automatically sets OpenCL to True? (link) That would definitely support the data you presented. You could probably test that idea by checking what the state of ocl::setUseOpenCL after you set it to false and then use an UMat.

最后,我猜你的CPU有一个内置的GPU。所以它正在使用OpenCL运行并行处理,并且没有花费时间来处理单独/专用的GPU并返回,因此你感觉到的性能比GPU增加(因为从技术上来说CPU不是运行它)...只有当你是专门使用 Mat 是仅使用的CPU。

Finally, I'm guessing your CPU has a built in GPU. So it is running parallel processing with OpenCL and not paying a time penalty to travel to the seperate/dedicated GPU and back, hence your perceived performance increase over the GPUs (since it is not technically the CPU running it)... only when you are specifically using the Mat is the CPU only being used.

你的上一个问题,我不确定。 ..这是我的推测:在GPU上存在OpenCL架构文件,当您使用CL安装CV时,您正在安装两个库和相关头文件之间的链接。我不确定你需要哪些dll文件来实现这种魔力。

Your last question, I'm not sure... this is my speculation: OpenCL architexture exists on the GPU, when you install CV with CL you are installing the link between the two libraries and associated header files. I'm not sure which dll files you need to make that magic happen.

这篇关于了解OpenCV中OpenCL的用法(Mat / Umat对象)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆