我在Android应用程序中有一些代码,当我分析我的应用程序时,它占用了大部分时间。我试图优化它,但仍占用大部分CPU时间。我想知道是否有人对如何加快这一点有任何想法。这是使用以下代码Im的精简版本:
输入:
d是数组浮点数
a是数组浮点数
e是数组浮点数
输出:
out是3个浮点数的数组
代码:
float [] c=new float[3];
float [] b=new float[3];
float [] out=new float[3];
c[0] = a[0] - d[0 * 4 + 3];
c[1] = a[1] - d[1 * 4 + 3];
c[2] = a[2] - d[2 * 4 + 3];
b[0] = c[0]*d[0 * 4 + 0] + c[1]*d[1 * 4 + 0] + c[2]*d[2 * 4 + 0];
b[1] = c[0]*d[0 * 4 + 1] + c[1]*d[1 * 4 + 1] + c[2]*d[2 * 4 + 1];
b[2] = c[0]*d[0 * 4 + 2] + c[1]*d[1 * 4 + 2] + c[2]*d[2 * 4 + 2];
out[0] = b[0] * e[0 * 4 + 0] + b[1] * e[0 * 4 + 1] + b[2] * e[0 * 4 + 2] + e[0 * 4 + 3];
out[1] = b[0] * e[1 * 4 + 0] + b[1] * e[1 * 4 + 1] + b[2] * e[1 * 4 + 2] + e[1 * 4 + 3];
out[2] = b[0] * e[2 * 4 + 0] + b[1] * e[2 * 4 + 1] + b[2] * e[2 * 4 + 2] + e[2 * 4 + 3];
对于那些对其3D模型动画的顶点变换感兴趣的人。 'out'是变换后的顶点,'a'原始顶点。其余的数组是骨架联合信息。
答案 0 :(得分:1)
其余代码的作用是什么?这看起来像一小段代码,所以它应该执行得非常快。你真的遇到性能问题,还是试图让你的程序根本没用CPU?
那就是说,你可以简单地预先计算所有那些简单的算术运算:
c[0] = a[0] - d[3];
c[1] = a[1] - d[7];
c[2] = a[2] - d[11];
等
我不明白你如何访问d[3]
,d[7]
和d[11]
,因为d
应该是一个包含3个元素的数组。
答案 1 :(得分:0)
你无能为力。所有的操作都是赋值和数学,你没有实现它们。另外,这些操作已经非常快......在某种类型的for循环中执行此操作会更高效,因为java必须在乘法之前存储所有这些数字。动态地做更有效。
答案 2 :(得分:0)
一次乘以零可以简化为零,然后删除添加,但我相信他们的编译器或热点已经可以做到。
您可以尝试memoising结果以防止重新计算。
此外,您可以尝试使用JCuda将此类数学计算机卸载到GPU中,但我不知道Android是否支持此类数据。
答案 3 :(得分:0)
所有编译时常量将(必须)由编译器进行常量折叠。您所能做的就是消除临时数组,无论如何您都不会将其用作数组。我试过这样的话:
public float[] transform2(float[] a, float[] d, float[] e)
{
float c0,c1,c2;
float b0,b1,b2;
float [] out=new float[3];
c0 = a[0] - d[0 * 4 + 3];
c1 = a[1] - d[1 * 4 + 3];
c2 = a[2] - d[2 * 4 + 3];
b0 = c0*d[0 * 4 + 0] + c1*d[1 * 4 + 0] + c2*d[2 * 4 + 0];
b1 = c0*d[0 * 4 + 1] + c1*d[1 * 4 + 1] + c2*d[2 * 4 + 1];
b2 = c0*d[0 * 4 + 2] + c1*d[1 * 4 + 2] + c2*d[2 * 4 + 2];
out[0] = b0 * e[0 * 4 + 0] + b1 * e[0 * 4 + 1] + b2 * e[0 * 4 + 2] + e[0 * 4 + 3];
out[1] = b0 * e[1 * 4 + 0] + b1 * e[1 * 4 + 1] + b2 * e[1 * 4 + 2] + e[1 * 4 + 3];
out[2] = b0 * e[2 * 4 + 0] + b1 * e[2 * 4 + 1] + b2 * e[2 * 4 + 2] + e[2 * 4 + 3];
return out;
}
您的代码需要35665毫秒来运行10000000000L
次迭代。 transform2()
花了20077ms所以它的速度有点快了两倍。两种方法都先预热,a [],d []和e []包含随机浮点数。
我想知道是否有可能通过使out
参数而不是在方法内部分配来改进事物,如果out
可以在外部保存,但在您的调用中可能无法实现码。然而,将其添加为第四个参数会使其更糟糕:它必须撤消一些HotSpot优化。但是当你在Android上时,如果可行,你可以考虑这个。
那是很多迭代......