为什么第一次拨打电话的费用比第二次拨打电话和第三次电话费用要多得多?等等?

时间:2017-10-09 01:22:22

标签: c++ function opencv time

以下是基于OpenCV的代码:

int main()
{
    clock_t start, stop;
    Mat img = imread("lena.jpg", IMREAD_GRAYSCALE);
    img.convertTo(img, CV_32F, 1.0);
    float *imgInP = (float *)img.data;    // get the input data point 
    Mat imgOut = Mat::zeros(Size(img.rows, img.cols), CV_32F);   // create output mat
    float *imgOutP = (float *)imgOutP.data;  // get the output data point

    // test several calling of opencv boxFilter
    start = clock();
    //blur(img, imgOut, Size(31, 31));
    boxFilter(img, imgOut, CV_32F, Size(31, 31));
    stop = clock();
    cout << "BoxFilter on OpenCV 1 : " << 1000.0 * (stop - start) / CLOCKS_PER_SEC << " ms" << endl;
    start = clock();
    //blur(img, imgOut, Size(31, 31));
    boxFilter(img, imgOut, CV_32F, Size(31, 31));
    stop = clock();
    cout << "BoxFilter on OpenCV 2 : " << 1000.0 * (stop - start) / CLOCKS_PER_SEC << " ms" << endl;
     start = clock();
    //blur(img, imgOut, Size(31, 31));
    boxFilter(img, imgOut, CV_32F, Size(31, 31));
    stop = clock();
    cout << "BoxFilter on OpenCV 3 : " << 1000.0 * (stop - start) / CLOCKS_PER_SEC << " ms" << endl;

    return 0;
}

以下是上述程序的输出:

OpenCV 1上的BoxFilter: 72.368ms

OpenCV 2上的BoxFilter: 0.495 ms

OpenCV 3上的BoxFilter: 0.403 ms

为什么第一次调用boxFilter(72.368ms)所花费的时间比第二次(0.495ms)和第三次调用<0.43ms(0.403ms)要多得多

更重要的是,如果我在第三次调用boxFilter时更改输入图像,输出也不会改变。因此,它可能不是图像数据缓存的因素......

感谢您的任何建议。

我的系统是Ubuntu 14.04,i5-4460,12GB RAM,OpenCV版本:3.1,cmake版本:3.2,g ++版本:4.8.4

以下是我的cmake文件:

cmake_minimum_required(VERSION 3.7)
project(boxfilterTest)

set(CMAKE_CXX_STANDARD 11)

find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})

set(SOURCE_FILES main.cpp)
add_executable(boxfilterTest ${SOURCE_FILES})

target_link_libraries(boxfilterTest ${OpenCV_LIBS})

IDE是CLion。

2 个答案:

答案 0 :(得分:3)

差异的原因是时间是由指令缓存和数据缓存引起的。可以通过强制将矩阵重新分配给不同的大小(例如,调整图像大小)来验证数据高速缓存。如果在boxFilter的不同调用之间调整图像大小,boxFilter调用的执行时间将变得非常接近。以下是演示上述现象的示例代码。

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
    clock_t start, stop;
    Mat img = imread("lena.jpg", IMREAD_GRAYSCALE);
    img.convertTo(img, CV_32F, 1.0);
    float *imgInP = (float *)img.data;    // get the input data point 
    Mat imgOut = Mat::zeros(Size(img.rows, img.cols), CV_32F);   // create output mat
    float *imgOutP = (float *)imgOut.data;  // get the output data point

    // test several calling of opencv boxFilter
    start = clock();
    //blur(img, imgOut, Size(31, 31));
    boxFilter(img, imgOut, CV_32F, Size(31, 31));
    stop = clock();

    cv::resize(img, img, cv::Size(), 1.1, 1.1); //Force data re-allocation

    cout << "BoxFilter on OpenCV 1 : " << 1000.0 * (stop - start) / CLOCKS_PER_SEC << " ms" << endl;
    start = clock();
    //blur(img, imgOut, Size(31, 31));
    //GaussianBlur(img, imgOut, Size(31, 31), 0.5);
    boxFilter(img, imgOut, CV_32F, Size(31, 31));
    stop = clock();

    cv::resize(img, img, cv::Size(), 0.909, 0.909);  //Force data re-allocation

    cout << "BoxFilter on OpenCV 2 : " << 1000.0 * (stop - start) / CLOCKS_PER_SEC << " ms" << endl;
     start = clock();
    //blur(img, imgOut, Size(31, 31));
    boxFilter(img, imgOut, CV_32F, Size(31, 31));
    stop = clock();
    cout << "BoxFilter on OpenCV 3 : " << 1000.0 * (stop - start) / CLOCKS_PER_SEC << " ms" << endl;

    return 0;
}

程序输出:

没有数据重新分配:

OpenCV 1上的BoxFilter:2.459 ms

OpenCV 2上的BoxFilter:1.599 ms

OpenCV 3上的BoxFilter:1.568 ms

使用数据重新分配:

OpenCV 1上的BoxFilter:2.225 ms

OpenCV 2上的BoxFilter:2.368 ms

OpenCV 3上的BoxFilter:2.091 ms

答案 1 :(得分:1)

嗯,我认为它可能是由指令缓存引起的(毕竟,CPU中有* MB L2缓存)。但我无法弄清楚如何验证并改进它。