有没有人将移动设备的处理能力与PC进行比较?我有一个非常简单的矩阵工作。用Java编写代码,我的旧PC完成工作需要大约115ms。非常非常相同的功能需要17000毫秒。我非常震惊。我没想到平板电脑会接近PC - 但我没想到它会慢〜150倍!
有没有人有类似的经历?有什么建议吗?如果我用C编写代码并使用Android NDK会有帮助吗?
Java中的基准代码:
package mainpackage;
import java.util.Date;
public class mainclass {
public static void main(String[] args){
Date startD = new Date();
double[][] testOut;
double[] v = {1,0,0};
double t;
for (int i = 0; i < 100000; i++) {
t=Math.random();
testOut=rot_mat(v, t);
}
Date endD = new Date();
System.out.println("Time Taken ms: "+(-startD.getTime()+endD.getTime()));
}
public static double[][] rot_mat(double v[], double t)
{
double absolute;
double x[] = new double[3];
double temp[][] = new double[3][3];
double temp_2[][] = new double[3][3];
double sum;
int i;
int k;
int j;
// Normalize the v matrix into k
absolute = abs_val_vec(v);
for (i = 0; i < 3; i++)
{
x[i] = v[i] / absolute;
}
// Create 3x3 matrix kx
double kx[][] = {{0, -x[2], x[1]},
{x[2], 0, -x[0]},
{-x[1], x[0], 0}};
// Calculate output
// Calculate third term in output
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j++)
{
sum = 0;
for (k = 0; k < 3; k++)
{
sum = sum + kx[i][k] * kx[k][j];
}
temp[i][j] = (1-Math.cos(t))*sum;
}
}
// Calculate second term in output
for (i = 0; i < 3; i++)
{
for (k = 0; k < 3; k++)
{
temp_2[i][k] = Math.sin(t)*kx[i][k];
}
}
// Calculate output
double[][] resOut = new double[3][3];
for (i = 0; i < 3; i++)
{
for (k = 0; k < 3; k++)
{
resOut[i][k] = temp_2[i][k] + temp[i][k] + ((i==k)?1:0);
}
}
return resOut;
}
private static double abs_val_vec (double v[])
{
double output;
output = Math.sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
return output;
}
}
答案 0 :(得分:0)
有什么建议吗?
微基准测试仅衡量微基准的表现。并且,解释微基准的唯一正确方法是使用微观测量。因此,精明的程序员会使用Traceview这样的工具来更好地了解他们的时间。
我怀疑如果你通过Traceview运行它,并查看LogCat,你会发现你的时间花在了两个方面:
内存分配和垃圾回收。你的微基准测试正在咀嚼~3MB的堆空间。在生产代码中,你永远不会这样做,至少如果你想保住你的工作。
浮点运算。根据您的平板电脑,您可能没有浮点协处理器,并且在CPU上进行浮点数学运算时,浮点协处理器的速度非常慢。
如果我用C编写代码并使用Android NDK会有帮助吗?
好吧,直到你在Traceview下分析代码,这将很难回答。例如,如果时间主要花费在sqrt()
,cos()
和sin()
上,那么已经是本机代码,并且您将无法获得更快的速度
更重要的是,即使这个微基准测试可能会使用本机代码进行改进,但所有这一切都证明了这个微基准测试可能会使用本机代码进行改进。例如,由于手动堆管理(malloc()
和free()
)而不是垃圾回收,因此对此的C转换可能会更快。但是,这更多地是对微基准编写得有多糟糕的起诉,而不是关于C将会多快多少的声明,因为生产Java代码将比这更优化。
除了学习如何使用Traceview之外,我建议:
阅读the NDK documentation,因为它包含有关本机代码何时有意义的信息。
阅读Renderscript Compute。在某些设备上,使用Renderscript Compute可以将整数数学卸载到GPU上,从而大幅提升性能。这不会对你的浮点微基准有所帮助,但对于其他矩阵计算(例如图像处理),Renderscript Compute可能值得研究。
答案 1 :(得分:0)
当您比较非常不同的架构时,单独处理能力并不是一切。实际上,您很可能不会单独对计算体系结构进行基准测试。
基准测试的关键因素。 当你处理需要考虑很多变量的事情时,隔离你要测试的那个,并保持其他人保持不变,最好等于。
在您的情况下,一些影响您的结果的变量示例:
答案 2 :(得分:0)
对于我的众多Android基准测试,PC和Android设备之间至少有八组比较。以下是我的Linpack基准测试(包括Java)的结果,它显示了Androids比您的结果更好的亮度。其他结果(如Dhrystone)表明,在每MHz的基础上,ARM的CPU可以匹配英特尔。
http://www.roylongbottom.org.uk/android%20benchmarks.htm
Linpack Benchmark Results
System ARM MHz Android Linpackv5 Linpackv7 LinpackSP NEONLinpack LinpackJava
See MFLOPS MFLOPS MFLOPS MFLOPS MFLOPS
T1 926EJ 800 2.2 5.63 5.67 9.61 N/A 2.33
P4 v7-A8 800 2.3.5 80.18 28.34 @G
T2 v7-A9 800 2.3.4 10.56 101.39 129.05 255.77 33.36
P5 v7-A9 1500 4.0.3 171.39 50.87 @G
T4 v7-A9 1500a 4.0.3 16.86 155.52 204.61 382.46 56.89
T6 v7-A9 1600 4.0.3 196.47
T7 v7-A9 1300a 4.1.2 17.08 151.05 201.30 376.00 56.44
T9 926EJ 800 2.2 5.66
T11 v7-A15 2000b 4.2.2 28.82 459.17 803.04 1334.90 143.06
T12 v7-A9 1600 4.1.2 147.07
T14 v7-A9 1500 4.0.4 180.95
P11 v7-A9 1400 4.0.4 19.89 184.44 235.54 454.21 56.99
P10 QU-S4 1500 4.0.3 254.90
Measured MHz a=1200, b=1700
Atom 1666 Linux 204.09 215.73 117.81
Atom 1666 Windows 183.22 118.70
Atom 1666 And x86 15.65
Core 2 2400 Linux 1288.00 901.00
Core 2 2400 Windows 1315.29 551.00
Core 2 2400 And x86 53.27
System - T = Tablet, P = Phone, @G = GreenComputing, QU = Qualcomm CPU
And 86 = Android x86