我有一个这样的循环:
double[][] ED = new double[n][m];
for(int k = 0; k < 20000; k++)
for (int i = 0; i < 200; i++)
for (int j = 0; j < 200; j++)
ED[i][j] = dis(qx[k][i], qy[k][i], dx[k][j], dy[k][j]);
“dis”是计算(x1,y1)和(x2,y2)之间的距离的函数。不介意。问题是当我在循环中添加另一个布尔赋值时,就像这样:
double[][] ED = new double[n][m];
boolean[][] bool = new boolean[n][m];
for(int k = 0; k < 20000; k++)
for (int i = 0; i < 200; i++)
for (int j = 0; j < 200; j++)
{
ED[i][j] = dis(qx[k][i], qy[k][i], dx[k][j], dy[k][j]);
bool[i][j] = ED[i][j] > 5000;
}
新循环比第一个循环花费1.5倍。我觉得它花了太多钱。为了测试,我将2个分配分成2个循环。奇怪的是,两个时间成本相同。有时,代码3比代码2花费更少的时间
double[][] ED = new double[n][m];
boolean[][] bool = new boolean[n][m];
for(int k = 0; k < 20000; k++)
{
for (int i = 0; i < 200; i++)
for (int j = 0; j < 200; j++)
{
ED[i][j] = dis(qx[k][i], qy[k][i], dx[k][j], dy[k][j]);
}
for (int i = 0; i < 200; i++)
for (int j = 0; j < 200; j++)
{
bool[i][j] = ED[i][j] > 5000;
}
}
我的目标是使用更少的时间来计算bool [i] [j],我该怎么做。
答案 0 :(得分:1)
引入新的大数组bool [] []可能比看起来更具影响力。 当仅使用单个arrayED [i] [j]时,可以减轻L1处理器缓存的压力。 对于第二个数组,您有两倍的数据,因此缓存将更频繁地失效。
你能尝试,而不是使用两个数组(bool和arrayED)使用同时包含double和boolean的单个数组吗?对象数组会有很大的开销,但是(也许)编译器会足够智能地去构造对象。
使用单个数组,您将拥有更好的数据位置。
另外,正如评论中所建议的那样,请确保正确进行微基准测试。 使用http://openjdk.java.net/projects/code-tools/jmh/并阅读其文档如何正确使用它。
另一种有助于多核系统的解决方案是使用并行处理。您可以创建ThreadPoolExecutor
(池大小等于您拥有的核心数),然后将每个操作作为任务提交给执行程序。操作可能是最内层循环(带有计数器j
),甚至可能是两个最内层循环(带有计数器i
和j
)。
协调工作会有一些开销,但如果你有4或8个核心,执行时间应该快得多。
另一个想法是改变输入数据结构。你可以使用单个数组,而不是在4个二维数组(qx,qy,dx,dy
)上运行吗?它可以使dis
功能更快。