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

Longer execution time of OpenCV function cv::remap() when program is put to sleep in between

本文关键字:两者之间 程序 状态 remap cv 函数 OpenCV 执行时间      更新时间:2023-10-16

我正在使用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;
}

如果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

但是,如果我将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

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

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

有人知道发生了什么吗?

这可能是您的 CPU 频率缩放开始了。

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

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

sudo cpupower frequency-set -g performance

效果立即消失了。要设置调速器,请执行

sudo cpupower frequency-set -g ondemand