4

有没有人将移动设备的处理能力与 PC 进行比较?我有一个非常简单的矩阵工作。用 Java 编码,我的旧 PC 大约需要 115 毫秒才能完成工作。非常非常相同的功能需要 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;
    }


}
4

3 回答 3

0

有什么建议吗?

微基准仅衡量微基准的性能。而且,解释微基准的唯一体面方法是使用微测量。因此,精明的程序员会使用 Traceview 之类的工具来更好地了解他们的时间都花在了哪里。

我怀疑如果你通过 Traceview 运行它,并查看 LogCat,你会发现你的时间花在了两个方面:

  1. 内存分配和垃圾收集。您的微基准测试正在消耗约 3MB 的堆空间。在生产代码中,你永远不会这样做,至少如果你想保住工作的话。

  2. 浮点运算。根据您的平板电脑,您可能没有浮点协处理器,并且在没有浮点协处理器的 CPU 上进行浮点数学运算非常慢。

如果我用 C 编写代码并使用 Android NDK 会有帮助吗?

好吧,除非您在 Traceview 下分析代码,否则很难回答。例如,如果时间主要花在sqrt()cos()sin()上,那已经本机代码,你不会变得更快。

更重要的是,即使这个微基准测试可能会随着原生代码而改进,但所做的只是证明这个微基准测试可能会随着原生代码而改进。例如,由于手动堆管理(malloc()free())而不是垃圾收集,对此的 C 翻译可能会更快。但这更多是对微基准编写得多么糟糕的控诉,而不是关于 C 将快多少的声明,因为生产 Java 代码将比这更好地优化。

除了学习如何使用 Traceview,我建议:

  • 阅读NDK 文档,因为它包含有关本机代码何时有意义的信息。

  • 阅读Renderscript Compute。在某些设备上,使用 Renderscript Compute 可以将整数数学卸载到 GPU 上,从而大幅提升性能。这对您的浮点微基准测试没有帮助,但对于其他矩阵计算(例如,图像处理),Renderscript Compute 可能非常值得研究。

于 2014-02-09T23:34:34.067 回答
0

当您比较非常不同的架构时,仅处理能力并不是一切。事实上,您很可能不会单独对计算架构进行基准测试。

基准测试的一个关键因素。当您处理需要考虑很多变量的事物时,隔离您要测试的变量,并保持其他变量不变,最好是相等的。

在您的情况下,一些影响结果的变量示例:

  • 实际的计算架构,它本身就是一组复杂的变量(处理器设计和实现、内存层次结构等)
  • 操作系统
  • 上述不同变量的不同Java 虚拟机实现
  • Dalvik 暗示的附加层
于 2014-02-09T23:34:47.940 回答
0

在下面我的众多 Android 基准测试中,至少有八组 PC 和 Android 设备之间的比较。以下是我的 Linpack 基准测试(包括 Java)的结果,它比您的结果更清楚地显示了 Android。其他结果(如 Dhrystone)表明,在每 MHz 的基础上,ARM 的 CPU 可以与 Intel 相媲美。

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
于 2014-02-10T10:25:51.610 回答