Caliper:微观和宏观基准

时间:2013-04-05 12:30:25

标签: java benchmarking caliper microbenchmark

对于ELKI,我需要(并且拥有)比标准Java JDK和Collections API提供的更灵活的排序实现。 (排序不是我的最终目标。我使用部分排序来批量加载索引结构,例如kd-tree和R * -tree,我希望对这些结构进行相当通用的实现,比ELKI目前更通用 - 但不管怎样,优化排序意味着优化索引构建时间。

但是,排序算法根据您的数据大小而有很大差异。对于小型数组,已知的事实是插入排序可以很好地执行(事实上,大多数快速排序实现将回退到低于某个阈值的插入排序);不是通过理论,而是通过排序理论不考虑的CPU流水线和代码大小效应。

所以我现在正在对许多排序实现进行基准测试,以便根据我的特定需求找到最佳组合;我希望我的更灵活的实现与JDK默认实现(已经很好地调整,但可能用于不同的JDK版本)相当。

从长远来看,我需要这些东西易于重现和重新运行。在某些时候,我们将看到JDK8。在Dalvik VM上,结果也可能与Java 7不同。哎呀,他们甚至可能在AMD,Core i7和Atom CPU上也有所不同。 因此,Cervidae可能会包含不同的排序策略,并在课程加载时选择最合适的排序策略。

我目前的努力是在GitHub:https://github.com/kno10/cervidae

现在谈到实际的问题。最新的caliper commit为macrobenchmarks添加了一些实验代码。但是,我面临的问题是我需要两个。当运行时间小于定时器分辨率的0.1%时,Caliper宏基准测试失败;有10000个对象,一些算法达到了这个阈值。与此同时,microbenchmarks抱怨说,当你的运行时间过长时,你应该做一个宏基准测试......

因此,对于不同排序大小的基准测试,我实际上需要一种根据运行时动态从微基准标记切换到宏基准标记的方法。 事实上,我甚至更喜欢如果caliper会自动地意识到运行时对于宏基准测试来说足够大,然后只进行一次迭代。

现在,我正试图通过使用:

来模仿这个
@Macrobenchmark
public int macroBenchmark() { ... }

public int timeMicroBenchmark(int reps) {
    int ret = 0;
    for (int i = 0; i < reps; i++) {
        ret += macroBenchmark();
    }
}

在两种方案中共享基准测试代码。另一个代码是使用

@Macrobenchmark
public int macroBenchmark() {
    return timeMicroBenchmark(1);
}

public int timeMicroBenchmark(int reps) { ... }

两个“适配器”中哪一个更受欢迎?从微观一直到宏的任何其他提示,以获得一致的基准测试?

鉴于卡尺WebUI当前不起作用,您使用什么来分析结果?我目前正在使用一个小的python脚本来处理JSON结果并报告加权方法。事实上,我喜欢旧文本报告比Web UI更好。

哦,有没有办法让Caliper在基准测试循环中发生Hotspot编译时重新运行基准测试?现在它记录了一个错误,但也许它可以重新启动那部分基准测试?

1 个答案:

答案 0 :(得分:6)

我认为问题在于微基准测试仪器的输出被误解为“投诉”。它说:

  

“信息:此实验不需要微基准测试。计时器的粒度(%s)小于测量运行时间的0.1 %%。如果此基准测试的所有实验的运行时间大于%s,请考虑宏基准测试仪器“。

该消息的具体措辞是传达个人实验很长,但由于该基准测试方法的其他实验可能不是,所以肯定不是错误。微基准测试仪器有更多的开销,但是虽然您的实验可能不需要微基准测试,但结果仍然完全有效。