CPU 计算能力基准测试

问题描述 投票:0回答:2

我正在尝试使用一个简单的函数来对CPU计算能力进行基准测试,而不是在我的项目中添加具有数千行和一些MB的巨大框架。

我开发了这个示例代码。这是一项需要完成 100 倍的艰巨任务。这项艰巨的任务(benchmark() 函数)需要一段时间,它将在 100 毫秒的时间内进行复杂的数学计算并增加计数器。每 100 毫秒就会在日志中打印 benchmark() 函数完成复杂数学计算的次数。

好的,所以,我已经在屏幕上打印了 100 次计算结果。

第一次执行基准测试时,我得到了正确的结果,基准测试的 100 次迭代中的每一次或多或少都有相同的日志结果:

08-18 13:09:52.806 26543-27748/com.mytestapp D/XXXX: Iteration: 0 Result: 118200
08-18 13:09:52.906 26543-27748/com.mytestapp D/XXXX: Iteration: 1 Result: 171580
08-18 13:09:53.006 26543-27748/com.mytestapp D/XXXX: Iteration: 2 Result: 170654
08-18 13:09:53.106 26543-27748/com.mytestapp D/XXXX: Iteration: 3 Result: 168676
08-18 13:09:53.206 26543-27748/com.mytestapp D/XXXX: Iteration: 4 Result: 168372
08-18 13:09:53.306 26543-27748/com.mytestapp D/XXXX: Iteration: 5 Result: 165558
08-18 13:09:53.406 26543-27748/com.mytestapp D/XXXX: Iteration: 6 Result: 171368
08-18 13:09:53.506 26543-27748/com.mytestapp D/XXXX: Iteration: 7 Result: 171680
08-18 13:09:53.606 26543-27748/com.mytestapp D/XXXX: Iteration: 8 Result: 171516
08-18 13:09:53.706 26543-27748/com.mytestapp D/XXXX: Iteration: 9 Result: 171598

但是在执行了一些之后,数量开始减少,我不明白为什么:

08-18 13:10:20.850 26543-28161/com.mytestapp D/XXXX: Iteration: 1 Result: 94320
08-18 13:10:20.951 26543-28161/com.mytestapp D/XXXX: Iteration: 2 Result: 90364
08-18 13:10:21.051 26543-28161/com.mytestapp D/XXXX: Iteration: 3 Result: 94240
08-18 13:10:21.152 26543-28161/com.mytestapp D/XXXX: Iteration: 4 Result: 93676
08-18 13:10:21.252 26543-28161/com.mytestapp D/XXXX: Iteration: 5 Result: 91554
08-18 13:10:21.352 26543-28161/com.mytestapp D/XXXX: Iteration: 6 Result: 94358
08-18 13:10:21.452 26543-28161/com.mytestapp D/XXXX: Iteration: 7 Result: 90954
08-18 13:10:21.552 26543-28161/com.mytestapp D/XXXX: Iteration: 8 Result: 94874
08-18 13:10:21.652 26543-28161/com.mytestapp D/XXXX: Iteration: 9 Result: 94464

如果我等待几分钟并重试,结果会再次增加到正常值。

为什么会有这种行为?如何避免它并始终获得正确的基准测试结果?

这是我的示例代码:

public void benchmarkIterator(){
    int result = 0;
    int iterations = 100;
    for (int i=0; i<iterations; i++){
       result = benchmark();
       Log.d("XXXX", "Iteration: "+i+" Result: "+result);
    }
}

....

     public int benchmark(){
        long startTime = System.currentTimeMillis();
        int count=0;
        double aux=0;
        while((System.currentTimeMillis()-startTime)<100){
            count++;
            double d = 7777777777d;
            aux = 0;
            aux=aux+(int)(aux+Math.sin(d)*Math.cos(d));
        }
        return count;
    }
java android math benchmarking computation
2个回答
1
投票

过热?不,我怀疑这个计算能让你的CPU出汗。

我认为随着时间的推移发生的变化与 JVM 和统计数据有关。 HotSpot 编译器使用它们根据代码正在执行的操作来优化代码分支。

http://blog.takipi.com/jvm-performance-magic-tricks/

https://wiki.openjdk.java.net/display/HotSpot/PerformanceTechniques

了解正在发生的情况的唯一方法是使用分析器。您需要查看垃圾收集、内存以及时间花在哪里。您的简单基准不会给您那种洞察力。


0
投票

如果我理解正确的话,这两个日志片段是针对不同的 JVM 启动进行的不同执行?

在这种情况下,两者之间的差异不可能是由 JVM 引起的(因为它已重新启动)。

因此,差异可能是由很多东西引起的:操作系统文件缓存(已经有一些文件正在运行)、CPU 电源管理(CPU 频率在不使用时下降可能需要一些时间才能恢复到最大值)频率)、主机上运行的其他内容(如果是虚拟机……可能会发生很多事情)、CPU 优化(如预取的分支预测)、...

无论如何,你没有问题,这只是现在计算机/jvm/cpu 的工作方式......

© www.soinside.com 2019 - 2024. All rights reserved.