我写了一段C代码,它使用有限差分法来估计值。这是一种平均方法。我分析了代码,发现一个iterate()
函数是最慢的。
void iterate(double data[][ARRAY_SIZE], int nx, int ny, int dx, int dy)
{
for (int i = 0; i < nx; ++i)
{
for (int j = 0; j < ny; ++j)
{
if (i % (dx + 1) == 0 && j % (dy + 1) == 0)
continue;
else if (i == 0 && 0 < j && j < ny)
data[i][j] = (data[i][j - 1] + data[i][j + 1] + data[i + 1][j]) / 3;
else if (j == 0 && 0 < i && i < nx)
data[i][j] = (data[i - 1][j] + data[i + 1][j] + data[i][j + 1]) / 3;
else if (i == nx - 1 && 0 < j && j < ny)
data[i][j] = (data[i][j - 1] + data[i][j + 1] + data[i - 1][j]) / 3;
else if (j == ny - 1 && 0 < i && i < nx)
data[i][j] = (data[i - 1][j] + data[i + 1][j] + data[i][j - 1]) / 3;
else
data[i][j] = (data[i - 1][j] + data[i + 1][j] + data[i][j - 1] + data[i][j + 1]) / 4;
}
}
}
这个循环运行得很慢,我不确定这里缺少什么使它变慢。有没有更好的方法来做同样的事?
使用
400x400
double
数组进行2000次迭代real 0m1.950s
user 0m1.940s
sys 0m0.004s
最佳答案
以下是一些想法:
似乎ny
必须等于ARRAY_SIZE
。您也可以省略它作为参数,而只使用编译时常量。
除最后一个if/else子句外,所有if/else子句仅适用于特定的行或列。所以把它们吊起来。例如,您可以将第一行和第一列作为1D循环处理,然后在边缘外部执行整个矩阵,最后处理最右边的列和最下面的行。
最后,核心循环应该更像这样:
for (int i = 1; i < nx - 1; ++i)
{
for (int j = 1; j < ARRAY_SIZE - 1; ++j)
{
data[i][j] = (data[i - 1][j] + data[i + 1][j] + data[i][j - 1] + data[i][j + 1]) / 4;
}
}