问题描述
我正在使用C ++和Eigen库来完成匹配任务。但是,结果效率很低。下面将描述任务和我当前的解决方案。
任务
该任务涉及两个大小相同的大地图mapL
和mapR
。匹配过程按行进行。例如,r-th
的{{1}}行中的元素将与mapL
的{{1}}行中的元素匹配。两个匹配元素的值可能不完全相同,因此我需要在r-th
中寻找差异最小的元素。
要计算差异,请执行以下步骤:
示例
一个示例将有助于理解上述过程。假设我们有
mapR
对于mapR
中的第一个元素,我想获得向量mapL
用于后续的计算
mapL
当前解决方案
在构建C ++代码时,我尝试使用mapL = [ 1 2 3 4,5;
6 7 8 9 10;
11 12 13 14 15];
mapR = [ 5 4 3 2,1;
10 9 8 7 6;
15 14 13 12 11];
和mapL
对过程进行矢量化处理。下面显示了示例代码:
difference
问题
上面的代码在我的机器上(VS 2017,发布模式,x64)大约需要61s来遍历每一行。我已经在MATLAB中实现了类似的代码,仅需6秒钟。有什么方法可以提高C ++代码的效率吗?我刚接触C ++,因此,如果我错过任何重要的概念,请告诉我。非常感谢!
编辑
经过更多测试,我发现了一种更有效的方法来完成任务。对我的原始代码进行性能分析表明,difference = [5 4 3 2 1] - [1] = [4 3 2 1 0];
和.replicate
操作消耗了大量的计算能力(〜90%)。使用嵌套循环需要不到3s的时间才能完成相同的任务。新代码如下:
.colwise
解决方法
两个建议:
-
默认情况下,Eigen按列优先顺序存储矩阵。通过定义
,使用行优先顺序可能会有所帮助using RowMajorMatrixXf = Matrix<float,Dynamic,RowMajor>;
并使用它而不是
MatrixXf
来使行在内存中是连续的。 -
.row(r)
方法返回一个表达式对象,该对象本身并不复制内存。但是将其分配给VectorXf或ArrayXf会创建一个副本。您可以按住decltype(mapL)::RowXpr rowL = mapL.row(r)
之类的表达式对象来消除副本。