Более длительное время выполнения функции OpenCV cv :: remap (), когда программа переводится в спящий режим между - PullRequest
0 голосов
/ 03 сентября 2018

Я выполняю некоторую обработку изображения, используя библиотеку 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.

Кто-нибудь имеет представление о том, что происходит?

1 Ответ

0 голосов
/ 03 сентября 2018

Это, вероятно, масштабирование частоты вашего процессора.

Стандартным регулятором частоты в Linux обычно является «ondemand», что означает, что тактовая частота уменьшается при низкой нагрузке на ЦП, и понижается при увеличении нагрузки. Поскольку этот процесс занимает некоторое время, ваши короткие пакеты вычислений не могут повысить тактовую частоту, и ваш процесс эффективно работает на более медленном процессоре , чем на самом деле.

Я проверил эту теорию на моей машине, выполнив

sudo cpupower frequency-set -g performance

и эффект сразу исчез. Чтобы вернуть регулятор обратно, выполните

sudo cpupower frequency-set -g ondemand
...