卡尺:微基准和宏基准

4
对于ELKI,我需要(并且已经有了)比Java JDK和Collections API提供的更灵活的排序实现。(排序不是我的终极目标。我使用部分排序来进行索引结构的批量加载,例如k-d树和R * -tree,并且我想使这些结构的相当通用的实现可用,比当前在ELKI中的更通用-但无论如何,优化排序意味着优化索引构建时间)。
然而,排序算法的规模因您的数据大小而异。对于微小的数组,众所周知插入排序可以表现良好(事实上,大多数快速排序实现将在某个阈值以下回退到插入排序);这不是通过理论,而是通过CPU流水线和代码大小效应,这些效应在排序理论中没有考虑。
因此,我目前正在基准测试一些排序实现,以找到最适合我的特定需求的最佳组合;我希望我的更灵活的实现与JDK默认实现有些相似(它们已经调整得很好,但可能适用于不同的JDK版本)。
从长远来看,我需要这些东西易于复制和重新运行。在某个时候,我们将看到JDK8。在Dalvik VM上,结果可能与Java 7上的结果也不同。甚至在AMD、Core i7和Atom CPU上也可能不同。因此,也许Cervidae将包括不同的排序策略,并在类加载时间上选择最合适的策略。
我的当前工作在GitHub上: https://github.com/kno10/cervidae 现在是实际问题。最新的caliper提交添加了一些用于宏基准测试的实验代码。然而,我面临的问题是我需要两者都有。当运行时间小于计时器分辨率的0.1%时,Caliper宏基准测试失败;对于10000个对象,一些算法达到了此阈值。同时,微基准测试抱怨说当运行时间过长时,你应该做一个宏基准测试...

因此,为了对不同的排序大小进行基准测试,我需要一种动态切换微基准测试和宏基准测试的方法,具体取决于运行时间。 实际上,我甚至希望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) { ... }

哪一个“适配器”更好?有没有其他提示可以使微观到宏观的基准测试更加一致?
考虑到caliper WebUI目前不可用,你使用什么来分析结果?我目前正在使用一个小型python脚本来处理JSON结果并报告加权平均值。事实上,我更喜欢旧的文本报告而不是Web UI。
哦,是否有办法让Caliper在基准测试循环中发生Hotspot编译时重新运行基准测试?现在它会记录一个错误,但也许它可以重新启动基准测试的那部分?

2
也许对你来说已经太晚了,但是OpenJDK中有一个新的基准测试工具(在几周前推出):http://openjdk.java.net/projects/code-tools/jmh/,它应该解决一些使用caliper时遇到的问题。由Oracle的一些性能工程师创建。免责声明:我还没有尝试过,但它似乎很有前途。 - assylias
2
谢谢。JMH看起来很有前途。因为它似乎比caliper更少关注Web UI。此外,它不会引入太多依赖项。我真的很讨厌许多当前的Java项目中到处都是大量的依赖链。例如,Caliper也不例外,依赖于Hibernate,至少又引入了另外20个依赖项。也许我会尝试一下 - 越早越好。例如,我还没有开始将我的堆基准更新到caliper 1.0。这些基准还需要比排序更复杂的工作负载。 - Erich Schubert
@assylias,JMH在哪些方面比Caliper更出色?对我来说,实际上看起来Caliper使用了更先进的技术(尽管有点过于臃肿)。 - Erich Schubert
1
@assylias FWIW,我们看到了那个基准测试及其评论,并对各种原因持有怀疑态度。Caliper使用的方法是综合了许多长期Java库和平台开发人员的专业知识和建议。话虽如此,JMH有一些值得探究的有趣方面和一些比较分析需要进行,但遗憾的是我无法构建它。 - gk5885
@gk5885 这确实很有趣 - 你也可以在他们的邮件列表上发布,以引发讨论。顺便说一下,我成功地在Netbeans/Windows 7上作为Maven项目构建了它,而且非常顺利。 - assylias
显示剩余6条评论
1个回答

6
我认为问题在于微基准测试工具的输出被误解为“投诉”。它说:
“INFO: This experiment does not require a microbenchmark. The granularity of the timer (%s) is less than 0.1%% of the measured runtime. If all experiments for this benchmark have runtimes greater than %s, consider the macrobenchmark instrument.”
这个信息是特别用来表达一个“单独实验”很长,但由于该基准方法的其他实验可能不是这样,所以它肯定不是一个错误。微基准测试工具有一些额外的开销,但是虽然你的实验不需要微基准测试,结果仍然是完全有效的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接