首页 > 解决方案 > OpenCV 改进了第一次 GPU 调用并减少了时间开销

问题描述

我有一些简单的 OpenCV 代码,如下所示:

        TIMING_START(T1);
        cv::cvtColor(fi.getUMat(cv::ACCESS_READ), fi_gray, CV_RGB2GRAY);
        TIMING_STOP(T1);
        TIMING_START(T2);
        cv::threshold(fi_gray, fi_gray, 70, 255, CV_THRESH_BINARY);
        TIMING_STOP(T2);
        TIMING_START(T3);
        cv::Canny(fi_gray, canny_output, 1, 255, 3);
        TIMING_STOP(T3);

我尝试完成的事情很好,所以代码的作用不是问题。问题是它需要的时间开销,因为我使用我的集成 GPU 和 OpenCV 3.3 支持 OpenCL 在 iGPU 上运行。这对于第一次之后的每个呼叫都非常有用。我知道初始化和编译 gpu 内核代码需要时间,但我在视频应用程序中使用这些代码,重点是实时性能。因此,第一次通话和图像总是需要 1.5 秒,并且显然会使视频断断续续。之后的调用在 < 10 毫秒内完成,这绝对没问题。

那么有没有办法在GPU代码编译并在之后使用GPU版本时切换到CPU变体?就这样我没有第一次“滞后”。

提前感谢您的建议!

标签: c++opencvvideoopencl

解决方案


如果您还没有这样做,另一种选择可能是缓存使用的任何 OpenCL 内核的二进制文件。(我对 OpenCV 一无所知,所以这个建议完全基于 OpenCL。)您可以使用clCreateProgramWithBinary()clGetProgramInfo(program, CL_PROGRAM_BINARY_SIZES, ...)/保存的二进制数据,而不是从源代码构建 OpenCL 程序clGetProgramInfo(program, CL_PROGRAM_BINARIES, ...)。您仍然需要在第一次运行时支付编译费用,或者更确切地说是在更改 OpenCL 实现/设备甚至驱动程序更新后的第一次运行时,但后续运行应该更快。(当然,关于尽早执行初始化并尽可能“隐藏”其运行时成本的建议仍然适用,并且可以与此结合使用。)


推荐阅读