繁体   English   中英

如何在c ++ 11中使用std :: vector使其更快?

[英]How Can I make it faster in c++11 with std::vector?

我有cv :: Mat Mat_A和cv :: Mat Mat_B都是(800000 X 512)浮点数

下面的代码看起来很慢。

int rows = Mat_B.rows;
cv::Mat Mat_A = cv::repeat(img, rows, 1, Mat_A);
Mat_A = Mat_A - Mat_B
cv::pow(Mat_A,2,Mat_A)
cv::reduce(Mat_A, Mat_A, 1, CV_REDUCE_SUM);
cv::minMaxLoc(Mat_A, &dis, 0, &point, 0);

如何在std :: vector中执行此操作?

我认为应该更快。

在我的2.4 GHz mabook pro中,花了4秒? 非常慢。

我不认为您应该使用std :: vector进行这些操作。 图像处理(CV,又称计算机视觉)算法在计算上往往很繁琐,因为要处理的数据太多。 OpenCV 2.0 C ++对此类操作进行了高度优化,例如cv :: Mat具有标头,并且每当使用复制分配或构造函数复制cv :: Mat时,仅标头会被复制并带有指向数据的指针。 他们使用引用计数来跟踪实例。 因此,内存管理已为您完成,这是一件好事。

https://docs.opencv.org/2.4/doc/tutorials/core/mat_the_basic_image_container/mat_the_basic_image_container.html

您可以尝试在没有调试符号的情况下进行编译,即发布与调试。 而且,您也可以尝试使用优化标志进行编译,例如针对gcc -O3,这将减少二进制文件的大小并加快运行时操作。 也许会有所作为。

https://www.rapidtables.com/code/linux/gcc/gcc-o.html

您可以尝试的另一件事是为进程赋予更高的优先级,即优先级越高,进程产生的CPU越少。 同样,这可能并没有太大的区别,这完全取决于其他流程及其优先级等。

https://superuser.com/questions/42817/is-there-any-way-to-set-the-priority-of-a-process-in-mac-os-x

我希望能有所帮助。

好吧,你的想法是错误的。

  1. 为什么您的程序运行缓慢:

您的CPU必须遍历大量数字并进行计算。 这将使计算复杂度很高。 这就是为什么它很慢。 程序的速度与Mat A和B的大小成比例。您可以通过减小/增大Mat A和B的大小来检查这一点。

  1. 我们可以通过std :: vector来加速它吗

对不起,不是。 使用std :: vector不会降低计算复杂度。 opencv的数学技巧是“最好的”,重写只会导致代码变慢。

  1. 如何加速计算:您需要启用opencv的加速选项

您可以在以下网址查看它: https : //github.com/opencv/opencv/wiki/CPU-optimizations-build-options 英特尔提供了英特尔mkl库来加速矩阵计算。 您可以先尝试一下。

就个人而言,最简单的方法是使用GPU。 但是您的计算机没有GPU,因此不在此处讨论范围。

您不断反复遍历数据以对其进行独立操作。

这样的事情只对数据进行一次迭代。

//assumes Mat_B and img cv::Mat
using px_t = float;//you mentioned float so I'll assume both img and Mat_B use floats
int rows = Mat_B.rows;
cv::Mat output(1,rows, Mat_B.type());
auto output_ptr = output.ptr<px_t>(0);
auto img_ptr = img.ptr<px_t>(0);
int min_idx =0;
int max_idx =0;
px_t min_ele = std::numeric_limits<px_t>::max();
px_t max_ele = std::numeric_limits<px_t>::min();
for(int i = 0; i< rows; ++i)
{
    output[i]=0;
    auto mat_row = Mat_B.ptr<px_t>(i);
    for(int j = 0; j< Mat_B.cols; ++j)
    {
        output[i] +=(img_ptr[j]-mat_row[j])*(img_ptr[j]-mat_row[j]);
    }
    if(output[i]<min_ele)
    {
       min_idx = i;
       min_ele = output[i];
    }
    if(output[i]>max_ele)
    {
       max_idx = i;
       max_ele = output[i];
    }
}

虽然我也不确定是否更快,但是假设Mat_B包含uchar ,您可以这样做

std::vector<uchar> array_B(Mat_B.rows* Mat_B.cols);
if(Mat_B.isContinuous())
    array_B = Mat_B.data;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM