gpt4 book ai didi

C++ Eigen 库 : Performance overhead of Ref<>

转载 作者:搜寻专家 更新时间:2023-10-31 01:27:47 26 4
gpt4 key购买 nike

我正在为计算力学使用 Eigen 编写一个通用库,主要处理 6x6 大小的矩阵和 6x1 大小的 vector 。我考虑使用 Eigen::Ref<>模板使其也可用于段和 block ,如 http://eigen.tuxfamily.org/dox/TopicFunctionTakingEigenTypes.html 中所述和 Correct usage of the Eigen::Ref<> class

然而,一个小的性能比较表明 Eigen::Ref与标准的 c++ 引用相比,这种小函数的开销相当大:

#include <ctime>
#include <iostream>
#include "Eigen/Core"


Eigen::Matrix<double, 6, 6> testRef(const Eigen::Ref<const Eigen::Matrix<double, 6, 6>>& A)
{
Eigen::Matrix<double, 6, 6> temp = (A * A) * A;
temp.diagonal().setOnes();
return temp;
}

Eigen::Matrix<double, 6, 6> testNoRef(const Eigen::Matrix<double, 6, 6>& A)
{
Eigen::Matrix<double, 6, 6> temp = (A * A) * A;
temp.diagonal().setOnes();
return temp;
}


int main(){

using namespace std;

int cycles = 10000000;
Eigen::Matrix<double, 6, 6> testMat;
testMat = Eigen::Matrix<double, 6, 6>::Ones();

clock_t begin = clock();

for(int i = 0; i < cycles; i++)
testMat = testRef(testMat);

clock_t end = clock();


double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;

std::cout << "Ref: " << elapsed_secs << std::endl;

begin = clock();

for(int i = 0; i < cycles; i++)
testMat = testNoRef(testMat);
end = clock();

elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;

std::cout << "noRef : " << elapsed_secs << std::endl;


return 0;
}

gcc -O3 输出:

Ref: 1.64066
noRef : 1.1281

看来 Eigen::Ref有相当大的开销,至少在实际计算量较低的情况下。另一方面,使用 const Eigen::Matrix<double, 6, 6>& A 的方法如果传递 block 或段,会导致不必要的拷贝:

#include <Eigen/Core>
#include <iostream>


void test( const Eigen::Vector3d& a)
{
std::cout << "addr in function " << &a << std::endl;
}

int main () {

Eigen::Vector3d aa;
aa << 1,2,3;
std::cout << "addr outside function " << &aa << std::endl;

test ( aa ) ;
test ( aa.head(3) ) ;


return 0;
}

输出:

addr outside function 0x7fff85d75960
addr in function 0x7fff85d75960
addr in function 0x7fff85d75980

所以这种方法被排除在一般情况下。

或者,可以使用 Eigen::MatrixBase 制作函数模板,如文档中所述。但是,这对于大型库来说似乎效率低下,并且不能像我的情况那样适应固定大小的矩阵(6x6、6x1)。

还有其他选择吗?大型通用库的一般建议是什么?

提前致谢!

编辑:根据评论中的建议修改了第一个基准示例

最佳答案

Ref<>你付出了失去两个信息的代价(与 Matrix 相比):

  1. 您不知道输入是内存对齐的。
  2. 您丢失了列按顺序存储的编译时知识(因此两列由 6 个 double 分隔)。

这是通用性和最高性能之间的经典权衡。

关于C++ Eigen 库 : Performance overhead of Ref<>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52801001/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com