【发布时间】:2011-07-01 03:14:49
【问题描述】:
我是多年使用 Matlab 进行数值编程的 C 新手。我已经开发了一个程序来解决一个大型的微分方程系统,但我很确定我做了一些愚蠢的事情,因为在分析代码之后,我惊讶地发现三个循环占用了大约 90% 的计算时间,尽管他们正在执行程序中最琐碎的步骤。
基于这些昂贵的循环,我的问题分为三个部分:
-
将数组初始化为零。当 J 被声明为双精度数组时,数组的值是否初始化为零?如果没有,有没有一种快速的方法将所有元素设置为零?
void spam(){ double J[151][151]; /* Other relevant variables declared */ calcJac(data,J,y); /* Use J */ } static void calcJac(UserData data, double J[151][151],N_Vector y) { /* The first expensive loop */ int iter, jter; for (iter=0; iter<151; iter++) { for (jter = 0; jter<151; jter++) { J[iter][jter] = 0; } } /* More code to populate J from data and y that runs very quickly */ } -
在求解过程中,我需要求解由 P = I - gamma*J 定义的矩阵方程。 P 的构造比求解它定义的方程组花费的时间更长,所以我正在做的事情可能是错误的。在下面相对较慢的循环中,访问包含在结构“数据”中的矩阵是慢速组件还是与循环有关的其他内容?
for (iter = 1; iter<151; iter++) { for(jter = 1; jter<151; jter++){ P[iter-1][jter-1] = - gamma*(data->J[iter][jter]); } } -
是否有矩阵乘法的最佳实践?在下面的循环中,Ith(v,iter) 是一个宏,用于获取保存在 N_Vector 结构“v”(日晷求解器使用的数据类型)中的向量的第 iter 个分量。特别是,有没有最好的方法来获得 v 和 J 的行之间的点积?
Jv_scratch = 0; int iter, jter; for (iter=1; iter<151; iter++) { for (jter=1; jter<151; jter++) { Jv_scratch += J[iter][jter]*Ith(v,jter); } Ith(Jv,iter) = Jv_scratch; Jv_scratch = 0; }
【问题讨论】:
标签: c optimization loops