c++ - 了解 OpenCL 在 OpenCV 中的用法(Mat/Umat 对象)

标签 c++ performance opencv image-processing opencl

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

  1. Just_mat()(不使用 OpenCL 作为 Mat 对象)
  2. Just_UMat()(不使用 OpenCL 作为 Umat 对象)
  3. OpenCL_Mat()(使用 OpenCL 作为 Mat 对象)
  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 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 UMa|
|________________________________________|
|--卡里佐---|------7.69052 ------ |-----0.247069-----|
|________________________________________|
|---岛屿--- |--------7.12455----- |-----0.233345-----|
|________________________________________|


________________________________________________________
|----CPU---|带有 OpenCL Mat |使用 OpenCl UMa |
|________________________________________|
|---AMD---|--------6.76169 ------ |--------0.231103--------|
|________________________________________|


________________________________________________
|----CPU---|没有 OpenCL Mat |没有 OpenCl UMa |
|________________________________________________________|
|----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 函数吗?

最佳答案

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 来指示两者在每个 GPU/CPU 上运行(更多关于“选择下面的 CPU”的信息)...阅读 this :

Few design choices support the new architecture:

  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.

  2. 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.

  3. 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 遗留代码,请务必小心。这样做是有原因的,但并不总是那么简单。但是,回到主题,当你说,

with OpenCL UMat

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

最后,我猜测您的 CPU 具有内置 GPU。因此,它使用 OpenCL 运行并行处理,而不需要花费时间来往返于单独/专用 GPU 上,因此您感知到的性能相对于 GPU 而言有所提高(因为从技术上讲,它不是运行它的 CPU)……只有当您专门使用 Mat 是仅使用的 CPU。

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

关于c++ - 了解 OpenCL 在 OpenCV 中的用法(Mat/Umat 对象),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41688751/

相关文章:

python - 跟踪相同颜色的多个对象

c++ - 访问全局数组比作为参数传递更有效?

c++ - 程序(使用 SFML)被检测为病毒/恶意软件/特洛伊木马

C++ 全局常量数组 : Is it guaranteed to be merged (optimized) into one copy?

python - 在 Python 中将键添加到字典或将值附加到列表是否更快?

c++ - 使用kinect从点云生成三角形网格的算法

c++ - 在 C++ 中为每个平台定义函数的首选方法是什么

objective-c - 如何找出 mach_msg_trap 等待什么?

mysql - 我使用这两个查询中的哪一个查询性能最好?

c++ - opencv2.4.13 中的 Min, Max, Avg 过滤器