当程序进入睡眠状态时,OpenCV函数cv :: remap()的执行时间更长

Mat*_*lič 4 c++ opencv image-processing execution-time remap

我正在使用OpenCV库进行一些图像处理,我发现处理图像所需的时间取决于我在图像处理之间让我的线程进入睡眠状态的时间.我测量了程序的几个部分的执行时间,并且我发现函数cv :: remap()似乎执行速度慢两倍,如果我让我的线程睡眠超过一段时间.

下面是显示奇怪行为的最小代码段.我测量执行cv :: remap()函数所花费的时间,然后我将我的威胁发送到sleep_time中设置的毫秒.

#include <opencv2/imgproc.hpp>
#include <thread>
#include <iostream>

int main(int argc, char **argv) {
  cv::Mat src = ... // Init
  cv::Mat dst = ... // Init

  cv::Mat1f map_x = ... // Init;
  cv::Mat1f map_y = ... // Init;

  for (int i = 0; i < 5; i++) {
    auto t1 = std::chrono::system_clock::now();
    cv::remap(src, dst, map_x, map_y, cv::INTER_NEAREST, cv::BORDER_CONSTANT, 0);
    auto t2 = std::chrono::system_clock::now();
    std::chrono::duration<double> elapsed_time = t2 - t1;
    std::cout << "elapsed time = " << elapsed_time.count() * 1e3 << " ms" << std::endl;

    int sleep_time = 0;
    // int sleep_time = 20;
    // int sleep_time = 100;
    std::this_thread::sleep_for( std::chrono::milliseconds(sleep_time));
  }

   return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果sleep_time设置为0,则处理大约需要5毫秒.这是输出.

elapsed time = 5.94945 ms
elapsed time = 5.7458 ms
elapsed time = 5.69947 ms
elapsed time = 5.68581 ms
elapsed time = 5.7218 ms
Run Code Online (Sandbox Code Playgroud)

但是如果我将sleep_time设置为100,则处理速度会慢两倍.

elapsed time = 6.09076 ms
elapsed time = 13.2568 ms
elapsed time = 13.4524 ms
elapsed time = 13.3631 ms
elapsed time = 13.3581 ms
Run Code Online (Sandbox Code Playgroud)

我为sleep_time尝试了许多不同的值,当sleep_timeelapsed_time(sleep_time > 3*elapsed_time)大约高三倍时,执行似乎加倍.如果我增加了函数cv :: remap()内的计算复杂度(例如增加处理图像的大小),那么sleep_time也可以在执行开始加倍之前设置为更高的值.

我在带有ARM操作系统的ARM处理器iMX6的嵌入式设备上运行我的程序,但我能够在运行Ubuntu 16.04的桌面上重新创建问题.我正在使用编译器arm-angstrom-linux-gnueabi-gcc(GCC)7.3.0Opencv版本3.3.0.

有人知道发生了什么吗?

n. *_* m. 6

这可能是你的CPU频率缩放.

Linux上的默认频率调控器通常是"按需",这意味着当CPU上的负载较低时,时钟速度会缩小,而当负载增加时,时钟速度会缩小.由于此过程需要一些时间,因此您的短计算突发无法使时钟速度提高,并且您的进程有效地运行在比实际速度慢的CPU上.

我通过执行在我的机器上测试了这个理论

sudo cpupower frequency-set -g performance
Run Code Online (Sandbox Code Playgroud)

并且效果立即消失.要重新设置调控器,请执行

sudo cpupower frequency-set -g ondemand
Run Code Online (Sandbox Code Playgroud)