我目前正在进行我的论文项目,设计一个与最短路径图算法一起使用的缓存实现。图形算法与运行时不一致,因此对整个算法进行基准测试太麻烦了。我必须集中精力对缓存进行基准测试。
我需要基准测试的缓存大约是Map
接口的十几个实现。这些缓存被设计为在给定的访问模式(从上面的算法中查询密钥的顺序)下工作良好。然而,在一个给定的"小"问题中,有几千亿个查询。我需要运行几乎所有的测试,才能对基准测试的结果充满信心。
关于将数据加载到内存中,我遇到了一些概念问题。可以创建一个查询日志,它只是在磁盘上按顺序列出在一次算法运行中查询的所有键(它们是10个字符串标识符)。这个文件是巨大的。我的另一个想法是将日志分解为1-50000个查询的块,并以以下方式进行基准测试:
- 加载1-50000个密钥
- 将开始时间设置为当前时间
- 按顺序查询
- 记录运行时间(当前时间-开始时间)
我不确定这会对缓存产生什么影响。我该如何进行热身?加载文件可能会清除最后一个块的L1或L2缓存中的任何数据。此外,维护一个1-500万元素的字符串数组有什么影响(甚至迭代它会扭曲结果吗)?
请记住,访问模式很重要!例如,有一些哈希表具有向前移动启发法,它对表的内部结构进行重新排序。多次运行单个区块或无序运行区块是不正确的。这使得预热CPU缓存和HotSpot变得有点困难(我也可以保留一个用于预热但不用于计时的辅助伪缓存)。
使用大型数据集进行微基准测试的良好做法是什么?
如果我正确理解了这个问题,那么在一台机器上加载查询日志(如果内存不足,可能会分块加载),然后通过专用网络(可能是交叉电缆)将其流式传输到运行基准测试的机器上,这样测试中的系统和测试代码/数据之间的干扰就最小了。。。?
无论你使用什么解决方案,你都应该尝试多次运行,这样你就可以评估可重复性——如果你没有获得合理的可重复性,那么你至少可以检测到你的解决方案不合适!
更新:re:批处理和定时-在实践中,您可能会使用某种形式的细粒度批处理,至少可以有效地通过网络获取数据。如果你的数据属于自然的大"组"或阶段,那么我会单独对它们进行计时,以检查异常情况,但最依赖的是整体计时。我看不出对成千上万的小批量进行计时有多大好处(考虑到你正在经历数百万)。
即使您在一台有大量RAM的机器上运行所有东西,也可能值得在一个JVM中加载数据,在另一个JVM上加载正在测试的代码,这样缓存JVM上的垃圾收集就不会(直接)受到保存查询日志所需的大堆的影响。