OpenCL占用大量CPU资源

时间:2019-01-22 14:24:57

标签: c++ opencv opencl nvidia

本质上,我正在使用OpenCV的OpenCL过滤器对OpenGL帧缓冲区进行后处理。一目了然,通过鼠标交互,一切都可以实时流畅,流畅地运行。但是,当我渲染一个稳定的场景时(即该进程应该处于空闲状态时),我意识到单核CPU的使用率很高,这潜在地跟随了最后一次交互几秒钟甚至半分钟。实际上,CPU的使用率一直存在,但不是在“我的”线程中(因此它不会阻塞任何东西),而是在NVidia的nvopencl.dll中在后台运行。

我的系统是:

Windows 10 64-bit
Intel Core i7-6820HQ
NVidia Quadro M4000M
nvopencl.dll as NVidia CUDA 9.0.176 OpenCL 1.2 Driver
Visual Studio 2015

我自己构建了OpenCV,没有OpenCV,该问题也可以重现,只是使复制变得更容易。要复制所有代码,将需要大量代码,但我设法将其包装如下。 (当然,该示例没有显示是否完成了任何图像过滤,但是在实际应用中,我可以轻松地验证每次finish调用之后确实发生了这种情况):

#include <windows.h>
#include <iostream>
#include <thread>
#include "opencv2/core.hpp"
#include "opencv2/core/ocl.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"


// Retrieves timing information for the specified process.
// millisecond units like GetTickCount()
double GetProcessTickCount(void )
{
    FILETIME c, e, k, u;
    GetProcessTimes(GetCurrentProcess(),&c,&e,&k,&u);
    ULARGE_INTEGER a,b;
    a.LowPart = k.dwLowDateTime;
    a.HighPart = k.dwHighDateTime;
    b.LowPart = u.dwLowDateTime;
    b.HighPart = u.dwHighDateTime;
    double t = 1000.0 * (double)( a.QuadPart + b.QuadPart ) * 100.0e-9;
    return t;
}
int main( void )
{
    // read any image file
    cv::Mat src = cv::imread("face1.png",cv::IMREAD_COLOR);
    std::cout << "Image size: "<< src.size() << std::endl;

#if 0
    cv::Mat dst;
    cv::ocl::setUseOpenCL(false); // explicit not to use OpenCL
    std::cout << "Without OpenCL" << std::endl;
    double t = cv::getTickCount();
    for ( int i=0;i<500;++i )
    {
        cv::bilateralFilter( src, dst, 15, 32.0, 8.0 );
    }
#else
    // copy into a UMat
    cv::UMat u, d;
    src.copyTo( u );
    // force using OpenCL
    cv::ocl::setUseOpenCL(true);
    double t = cv::getTickCount();
    for ( int i=0;i<500;++i )
    {
        // do bilateral filtering (on OpenCL, verify this by the debugger)
        cv::bilateralFilter( u, d, 15, 32.0, 8.0 );
        // finish the work
        cv::ocl::finish();
        // render the result, the finish is not required, but with OpenGL texture objects it kinda was...
        // ...
    }
#endif
    t = cv::getTickCount()-t;
    std::cout << "t=" << (t/cv::getTickFrequency()) << " seconds, fps=";
    std::cout << 500.0/(t/cv::getTickFrequency()) << std::endl;

    double cpuTime = 0;
    t = cv::getTickCount(); // wait time starts
    for ( ; ; std::this_thread::sleep_for( std::chrono::seconds(1) ) )
    {
        double time = GetProcessTickCount();
        // once we figure out CPU no more working on this process, we finish
        // !! note, first 1 second wait happens anyway
        if ( time - cpuTime > 2.0 ) // 2 ms to play safe
        {
            cpuTime = time;
        }else
            break;      
    }
    t = cv::getTickCount()-t; // wait time ends
    std::cout << "about to exit after waiting " << (t/cv::getTickFrequency()) << " seconds" << std::endl;
    return 0;
}

这里是带有印刷品

Image size: [640 x 960]
t=2.78591 seconds, fps=179.474
about to exit after waiting 21.0132 seconds
Press any key to continue . . .

并且没有OpenCL

Image size: [640 x 960]
Without OpenCL
t=10.9039 seconds, fps=45.8551
about to exit after waiting 1.00018 seconds
Press any key to continue . . .

这是探查器报告(clTryout是示例程序的名称): enter image description here

当然,问题是如何解决此问题?

*更新*

我无法在带有Intel i5-8250U和Intel OpenCL驱动程序的移动平台上重现此问题。请注意,等待时间为预期的1秒。看起来像是NVidia问题。

Image size: [640 x 960]
[ INFO:0] Initialize OpenCL runtime...
[ INFO:0] Preparing OpenCL cache configuration for context: Intel_R__Corporation--Intel_R__UHD_Graphics_620--23_20_16_4849
t=8.36944 seconds, fps=59.7411
about to exit after waiting 1.00269 seconds
Press any key to continue . . .

vs。

Image size: [640 x 960]
Without OpenCL
t=39.0353 seconds, fps=12.8089
about to exit after waiting 1.00778 seconds
Press any key to continue . . .

该问题已被问过,但尚未解决 Unexpected CPU utilization with OpenCL

0 个答案:

没有答案