以下是我正在开发的算法中最昂贵的部分。
到目前为止,绝对是一个热点-通过VisualVM检查。
经过一些优化技巧之后,例如展开3 ds
行,就已经有了。
当然,由于GAUSS_POINT_WEIGHTS
的元素数量固定为10,因此也可以尝试展开它,但这会产生100
可能的组合,因此我不确定是否值得(也许无论如何,JIT都会做。)
for (int i = 0; i < mesh.getDofsY(); i++) {
for (int k = 0; k < GAUSS_POINT_COUNT; k++) {
val x = GAUSS_POINTS[k] * dx + leftSegment;
for (int l = 0; l < GAUSS_POINT_COUNT; l++) {
val wk = GAUSS_POINT_WEIGHTS[k];
val wl = GAUSS_POINT_WEIGHTS[l];
val gl = GAUSS_POINTS[l];
val gk = GAUSS_POINTS[k];
if (i > 1) {
val y = (gl + (i - 2)) * dy;
val v = wk * wl * b1.getvalue(gl) * problem.valueAt(x,y);
ds.add(0,i,b3.getvalue(gk) * v);
ds.add(1,b2.getvalue(gk) * v);
ds.add(2,b1.getvalue(gk) * v);
}
if (i > 0 && (i - 1) < mesh.getElementsY()) {
val y = (gl + (i - 1)) * dy;
val v = wk * wl * b2.getvalue(gl) * problem.valueAt(x,b1.getvalue(gk) * v);
}
if (i < mesh.getElementsY()) {
val y = (gl + i) * dy;
val v = wk * wl * b3.getvalue(gl) * problem.valueAt(x,b1.getvalue(gk) * v);
}
}
}
}
在代码的这一部分中还有其他什么可以加速的(假设外部调用尽可能高效,这仅是关于此大量嵌套循环的事情)。我在问编译器特有的现象。
已经应用了下面的建议并有所帮助(请参阅pastebin),但似乎该热点中存在一个热点,它需要花费大量的计算时间或调用者循环(如上)。
即problem.valueAt(x,y)
转换为:
private double internalValueAt(double x,double y) {
val ielemx = (long) (x / mesh.getDx());
val ielemy = (long) (y / mesh.getDy());
val localx = x - mesh.getDx() * ielemx;
val localy = y - mesh.getDy() * ielemy;
val sp1x = b1.getvalue(localx);
val sp1y = b1.getvalue(localy);
val sp2x = b2.getvalue(localx);
val sp2y = b2.getvalue(localy);
val sp3x = b3.getvalue(localx);
val sp3y = b3.getvalue(localy);
return coef.doubleValue(0,ielemy) * sp1x * sp1y +
coef.doubleValue(0,ielemy + 1) * sp1x * sp2y +
coef.doubleValue(0,ielemy + 2) * sp1x * sp3y +
coef.doubleValue(1,ielemy) * sp2x * sp1y +
coef.doubleValue(1,ielemy + 1) * sp2x * sp2y +
coef.doubleValue(1,ielemy + 2) * sp2x * sp3y +
coef.doubleValue(2,ielemy) * sp3x * sp1y +
coef.doubleValue(2,ielemy + 1) * sp3x * sp2y +
coef.doubleValue(2,ielemy + 2) * sp3x * sp3y;
}
b1,b2 and b3
与主循环(b样条曲线)中的功能相同。也许我可以从外面通过它们,但这值得吗?
在我看来,这方面无能为力,但是也许您可以发现值得做的事情?让我知道做某事是否有任何先决条件。