Высокая и скрытая загрузка процессора с OpenCL - PullRequest
0 голосов
/ 22 января 2019

По сути, я использую OpenCL фильтры OpenCL для постобработки кадрового буфера OpenGL.В glimbse все работает хорошо и плавно в режиме реального времени с помощью мыши.Однако когда я рендерим устойчивую сцену, то есть когда процесс должен перейти в режим ожидания, я осознаю высокую загрузку одноядерного процессора, которая скрытно следует за последним взаимодействием, которое происходит за несколько секунд или даже за полминуты.На самом деле загрузка ЦП происходит постоянно, но не в «моем» потоке (поэтому он ничего не блокирует), а в фоновом режиме на nvopencl.dll от NVidia.

Моя система:

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

против

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

Вопрос был задан ранее, но не решен Неожиданная загрузка ЦП с OpenCL

...