我写了一段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;
        }
    }
}

这个循环运行得很慢,我不确定这里缺少什么使它变慢。有没有更好的方法来做同样的事?
使用400x400double数组进行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;
    }
}

08-16 20:49