Sur*_*ith 2 c++ performance opencv image-processing opencl
我运行下面的代码来检查 GPU 和 CPU 使用率之间的性能差异。我正在计算cv::cvtColor()函数的平均时间。我进行了四个函数调用:
Just_mat()(不使用 OpenCLMat对象)Just_UMat()(不使用 OpenCLUmat对象)OpenCL_Mat()(对Mat对象使用 OpenCL )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
Run Code Online (Sandbox Code Playgroud)
上述代码的输出(以毫秒为单位)为
__________________________________________
|GPU 名称|使用 OpenCL Mat | 使用 OpenCl UMat|
|_________________________________________|
|--Carrizo---|------7.69052 ------ |------0.247069-------|
|_________________________________________|
|---岛--- |-------7.12455------ |------0.233345-------|
|_________________________________________|
__________________________________________
|----CPU---|使用OpenCL Mat | 使用 OpenCl UMat |
|_________________________________________|
|---AMD---|------6.76169 ------ |--------0.231103--------|
|_________________________________________|
________________________________________________
|----CPU---| 没有 OpenCL Mat | 没有 OpenCl UMat |
|_________________________________________________________|
|----AMD---|------7.15959------ |------------0.246138------------ |
|_________________________________________________________|
在代码中,无论代码如何,使用 Mat 对象始终在 CPU 上运行,而使用 UMat 对象始终在 GPU 上运行ocl::setUseOpenCL(true/false);
任何人都可以解释所有输出时间变化的原因吗?
还有一个问题,我没有使用任何 OpenCL 特定的 .dll 和 .exe 文件,但使用 GPU 没有任何错误,在使用 Cmake 构建 OpenCV 时,我检查With_OpenCL了这是否构建了所有 OpenCL 所需的功能opencv_World310.dll?
在代码中,使用 Mat 对象总是在 CPU 上运行,而使用 UMat 对象总是在 GPU 上运行,而不管代码 ocl::setUseOpenCL(true/false);
对不起,因为我不确定这是一个问题还是一个陈述......在任何一种情况下它都是部分正确的。在 3.0 中,UMat如果您没有专用 GPU,那么 OpenCV 只会在 CPU 上运行所有内容。如果你特别要求Mat你把它放在 CPU 上。在您的情况下,您已经通过专门选择每个 GPU/CPU 来指示它们在每个 GPU/CPU 上运行(更多关于“选择下面的 CPU)...阅读此内容:
很少有设计选择支持新架构:
一个统一的抽象 cv::UMat,可以使用 CPU 或 OpenCL 代码实现相同的 API,而无需显式调用 OpenCL 加速版本。如果系统中存在,这些函数使用支持 OpenCL 的 GPU,否则自动切换到 CPU 操作。
UMat 抽象使函数能够被异步调用。与 OpenCV 2.x 版的 cv::Mat 不同,对 cv::UMat 的基础数据的访问是通过类的方法执行的,而不是通过其数据成员执行的。这种方法使实现能够仅在 CPU 代码绝对需要结果时才显式等待 GPU 完成。
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 只被使用。
你的最后一个问题,我不确定......这是我的猜测:OpenCL 架构存在于 GPU 上,当你使用 CL 安装 CV 时,你正在安装两个库和相关头文件之间的链接。我不确定您需要哪些 dll 文件才能实现这种魔力。