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



我有 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);

如何在标准::矢量中执行此操作?

我认为它应该更快。

在我的 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必须遍历大量数字并进行计算。这将使计算复杂度很高。这就是为什么它很慢。程序的速度与垫 A 和 B 的大小成正比。您可以通过减小/增加垫 A 和 B 的大小来检查这一点。

  1. 我们可以通过标准加速它吗::vector

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

  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;

最新更新