首页 > 解决方案 > 如何准确地对 C/C++ 代码进行基准测试?

问题描述

我在询问这个问题的答案,在我的回答中,我首先得到了循环前后的时间并打印出它们的区别,但是作为@cigiens 答案的更新,似乎我没有通过不加温来不准确地进行基准测试上代码。

什么是代码预热?我认为这里发生的事情是字符串首先被移动到缓存中,这使得以下循环的基准测试结果彼此接近。在我的旧答案中,第一个基准测试结果比其他结果慢,因为我认为将字符串移动到缓存需要更多时间,我正确吗?如果不是,那么热身实际上对代码做了什么,一般来说,如果可能的话,除了热身以获得更准确的结果之外,我还应该做什么?或者如何正确地对 C++ 代码进行基准测试(如果可能相同,也可以是 C)?

标签: c++cbenchmarking

解决方案


为了给你一个热身的例子,我最近对一些 nvidia cuda 内核调用进行了基准测试:

执行速度似乎随着时间的推移而增加,可能有几个原因,例如 GPU 频率是可变的(以节省电力和冷却时间)。

有时较慢的调用会对下一次调用产生更严重的影响,因此基准可能会产生误导。

如果您需要对这些要点感到安全,我建议您:

  • 首先保留所有动态内存(如向量)
  • 在测量之前创建一个 for 循环多次执行相同的工作
  • 这意味着在循环之前只初始化一次输入数据(尤其是随机的),并且每次在循环内复制它们以确保您做同样的工作
  • 如果您使用缓存处理复杂的对象,我建议您将它们打包在一个结构中并制作该结构的数组(使用相同的构造或克隆技术),以确保在相同的开始时完成相同的工作循环中的数据
  • 如果您经常交替两次调用并假设行为差异的影响将相互抵消,例如在模拟位置等连续数据时,您可以避免执行 for 循环并复制数据

关于测量工具,我总是在不同的机器上遇到 high_resolution_clock 的问题,比如持续时间的不一致。相反,windows QueryPerformanceCounter 非常好。

我希望这会有所帮助!

编辑

正如评论中所说,我忘了有效地添加,编译器优化行为可能很烦人。我发现的最简单的方法是根据预热和测量数据中的一些非平凡操作来增加变量,以便尽可能地强制顺序计算。


推荐阅读