c++ - 使用 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 中的一个(或两者)施加的约束?
解决方案
不要为此写作业。而是将数据复制到数组中。
我建议先从文件中读取值到std::vector<double> vec;
程序启动时。然后,您可以继续重用其内容。这也使得在不重新编译的情况下修改值变得更容易,并且编译器不必做太多不必要的工作。
然后
std::copy(vec.begin(), vec.end(), dydt);
这需要#include<algorithm>
forstd::copy
和#include<vector>
for std::vector
。
推荐阅读
- javascript - CSRF 令牌与 Laravel SPA 应用程序不匹配
- docker - 如何在 docker pull 之前从不安全的注册表中检查图像的压缩大小?
- r - 如何将来自不同源/数据集的图(线/迹线)动态添加到 R(闪亮)中的绘图对象?
- sql - 如何在 BigQuery 中连续四个星期循环过去六个月的数据
- spring-webflux - 转换单声道
- > 列出
- azure-devops - Azure DevOps 迁移工具附加子链接
- html - 获取动态加载表的列的总数
- flutter - 如何在单页中处理多个块?
- powershell - How to handle countdown in windows form using PowerShell?
- mysql - Why is select id slower than select * in MySQL