gpt4 book ai didi

c++ - Eigen :如何加速 += coeffs * coeffs.transpose()

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

我需要计算很多(大约 400k)个小型线性最小二乘问题的解。每个问题包含 10-300 个只有 7 个变量的方程式。为了解决这些问题,我使用了 eigen 库。直接求解会花费太多时间,我将每个问题都转化为通过亲手推导出导数来求解 7x7 线性方程组。

我收到了很好的加速,但我想再次提高性能。

我使用 vagrind 分析我的程序,我发现 self 成本最高的操作是特征矩阵的运算符 +=。这个操作需要十多次调用 a.ldlt().solve(b);

我用这个算子组成每个方程组的A矩阵和B vector

//I cal these code to solve each problem
const int nVars = 7;
//i really need double precision
Eigen::Matrix<double, nVars, nVars> a = Eigen::Matrix<double, nVars, nVars>::Zero();
Eigen::Matrix<double, nVars, 1> b = Eigen::Matrix<double, nVars, 1>::Zero();
Eigen::Matrix<double, nVars, 1> equationCoeffs;
//............................
//Somewhere in big cycle.
//equationCoeffs and z are updated on each iteration
a += equationCoeffs * equationCoeffs.transpose();
b += equationCoeffs * z;

其中 z 是一些标量

所以我的问题是:如何提高这些操作的性能?

PS 抱歉我的英语不好

最佳答案

您可以尝试一次分配一个足够大的矩阵(例如 300 x 7)来存储所有系数,然后让 Eigen 的优化矩阵代替手动形成正规方程的矩阵和 vector 分量,一次一个方程-矩阵乘积内核为您完成这项工作:

Matrix<double,Dynamic,nbVars> D(300,nbVars);
VectorXd f(300);
for(...)
{
int nb_equations = ...;
for(i=0..nb_equations-1)
{
D.row(i) = equationCoeffs;
f(i) = z;
}
a = D.topRows(nb_equations).transpose() * D.topRows(nb_equations);
b = D.topRows(nb_equations).transpose() * f.head(nb_equations);
// solve ax=b
}

对于矩阵 D,您可能同时使用列优先和行优先存储。看看哪个最好。

另一种可能的方法是声明 a , equationCoeffs , 和 b作为 8x8 或 8x1 矩阵或 vector 确保 equationCoeffs(7)==0 .这样您就可以最大限度地使用 SIMD。然后使用 a.topLeftCorners<7,7>() , b.head<7>()调用 LDLT 时。您甚至可以将此策略与之前的策略结合使用。

最后,如果您的 CPU 支持 AVX 或 FMA,您可以使用 devel 分支并使用 -mavx 编译或 -mfma获得显着的加速。

关于c++ - Eigen :如何加速 += coeffs * coeffs.transpose(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31472359/

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