我正在尝试学习一些基本的基准测试。我的Java程序中有一个循环,如
float a=6.5f;
int b=3;
for(long j=0; j<999999999; j++){
var = a*b+(a/b);
}//end of for
我的处理器需要大约0.431635秒来处理这个。如何根据触发器(每秒浮点运算)和Iops(每秒整数运算)计算处理器速度?你能用一些步骤提供解释吗?
答案 0 :(得分:2)
你有一个包含999999999迭代的循环:为简单起见,我们称之为1e9(十亿)。整数将在涉及两者的计算中被提升为浮点数,因此循环包含3个浮点运算:一个mult,一个add和一个div,所以有3e9。这需要0.432秒,所以你显然得到大约6.94 GFLOP / s(3e9 / 0.432)。类似地,每循环迭代您正在进行1整数运算(j++
),因此得到1e9 / 0.432或大约2.32 GIOP / s。
然而,计算a*b+(a/b)
是循环不变的,所以如果没有得到优化,那将是非常令人惊讶的。我对Java知之甚少,但任何C编译器都会在编译时对此进行评估,删除a
和b
变量以及循环,并(有效地)用{{替换整个批次1}}。这是一个非常基本的优化,所以如果var=21.667;
没有这样做,我会感到惊讶。
我不知道Java中的内幕是什么,但我对获得7 GFLOP感到怀疑。现代英特尔CPU(我假设你已经得到的)原则上能够在每个时钟周期内使用正确的指令混合(一个加法和每个周期一个多个)进行两个向量算术运算,因此对于3 GHz 4 -core CPU,甚至可以在理想条件下获得3e9 * 4 * 8 = 96个单精度GFLOP。各种javac
和mul
指令的倒数吞吐量为1个周期,但是add
需要的时间超过10倍,所以我对获得超过CLK的时间非常怀疑/ 12 FLOP(单核上的标量划分)一旦涉及到分区:如果编译器足够智能以对代码进行矢量化和/或并行化以获得更多,那么它必须要做的事情,它肯定会足够聪明到优化掉整个循环。
总之,我怀疑循环正在被完全优化,你所看到的0.432秒只是开销。你没有说明你如何计时上述循环,所以我不能确定。您可以通过用1e10替换~1e9循环迭代来自行检查。如果它不需要大约10倍的时间,你就不会计算你认为你正在计时的时间。
关于基准测试和分析还有很多话要说,但我会留下它。
我知道这已经很晚了,但我希望它有所帮助。
埃米特。