我写了一段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
答案 0 :(得分:3)
以下是一些想法:
ny
似乎必须等于ARRAY_SIZE
。您也可以省略它作为参数,只使用编译时常量。最后,你的核心循环应该更像这样:
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;
}
}
答案 1 :(得分:1)
考虑这个实现:
void iterate(double data[][ARRAY_SIZE], int nx, int ny, int dx, int dy)
{
// because nx - 1 and ny - 1 are used
nx--;
ny--;
// because dx + 1 and dy + 1 are used
dx++;
dy++;
int i = 0;
int j = 0;
// case i == 0 && 0 < j && j < ny
for (j = 1; j < ny; ++j)
{
if (j % dy)
data[0][j] = (data[i][j - 1] + data[i][j + 1] + data[i + 1][j]) / 3.0;
}
j = 0;
// case j == 0 && 0 < i && i < nx
for (i = 1; i < nx; ++i)
{
if (i % dx)
data[i][0] = (data[i - 1][j] + data[i + 1][j] + data[i][j + 1]) / 3.0;
}
// default case
for (i = 1; i < nx; ++i)
{
for (j = 1; j < ny; ++j)
{
if (i % dx || j % dy)
data[i][j] = (data[i - 1][j] + data[i + 1][j] + data[i][j - 1] + data[i][j + 1]) * 0.25;
}
}
// case i == nx && 0 < j && j < ny
for (j = 1; j < ny; ++j)
{
if (nx % dx || j % dy)
data[nx][j] = (data[i][j - 1] + data[i][j + 1] + data[i - 1][j]) / 3.0;
}
// case j == ny && 0 < i && i < nx
for (i = 1; i < nx; ++i)
{
if (ny % dy || i % dx)
data[i][ny] = (data[i - 1][j] + data[i + 1][j] + data[i][j - 1]) / 3.0;
}
}
主要的三点是:
/ 3.0
和* 0.25
)我的代码中唯一没有解释的是i % dx || j % dy
等于!(i % dx == 0 && j % dy == 0)
。