首页 > 解决方案 > 使用 GSL 减少 ODE 系统的编译资源

问题描述

我正在使用 C++ 和 GSL(Gnu 科学库)将大型 ODE 系统与 4503 方程集成。由于系统很僵硬,我需要设置一个雅可比行列式进行积分,得到的矩阵有大约 2000 万个条目。

为了初始化 ODE 系统和 Jacobian,GSL 需要使用具有特定签名的函数,即

int system(double t, const double y[], double dydt[], void *params);
int jac (double t, const double y[], double *dfdy, double dfdt[], void *params);

其中dydt[]*dfdy分别是系统和雅可比矩阵的数组。

我已经在两个单独的.cpp文件中声明了这些函数。对于系统,我有类似的东西

// ODESystem.cpp

int system(double t, const double y[], double dydt[], void *params) {
    (void)(t);
    double l = *(static_cast<double*>(params));

    dydt[0] = 0;

    // lots of assignment statements like the above

    return GSL_SUCCESS;
}

对于雅可比行列式,我有类似的东西

// ODEJacobian.cpp

int jacobian(double t, const double y[], double *dfdy, double dfdt[], void *params) {
    (void)(t);
    (void)(y);
    double l = *(static_cast<double*>(params));

    dfdy[0] = 0;

    // lots of assignment statements like the above

    return GSL_SUCCESS;
}

到目前为止,GCC 能够ODESystem.cpp很好地处理,但是编译需要很长时间(大约 45G 的 ram)ODEJacobian.cpp,(我想,这是可以理解的,因为这里的赋值操作的表达式树的大小怪物),但它最终这样做没有错误或警告。

Clang 似乎无法应付函数的大小,虽然它正常退出,但它会发出关于“到达非 void 函数的末尾并且找不到返回语句”的警告,这在我看来就像 clang “放弃”在雅可比函数结束之前在某处编译。然而,对于较小的尺寸(大约 5,745,609 个作业),Clang 可以正常工作并且不会发出任何警告。

我的问题是:在这种情况下,可以做些什么来减少编译雅可比行列式所需的资源量(时间和内存),同时尊重 GSL 对 GCC 和 Clang 中的一个(或两者)施加的约束?

标签: c++gccclangcompiler-optimizationgsl

解决方案


不要为此写作业。而是将数据复制到数组中。

我建议先从文件中读取值到std::vector<double> vec;程序启动时。然后,您可以继续重用其内容。这也使得在不重新编译的情况下修改值变得更容易,并且编译器不必做太多不必要的工作。

然后

std::copy(vec.begin(), vec.end(), dydt);

这需要#include<algorithm>forstd::copy#include<vector>for std::vector


推荐阅读