C++ 程序在重新执行时加速

Max*_*hon 3 c++ ubuntu performance memory-management clion

我目前正在对 C++ 程序进行性能测试。我需要批量插入一个std::unordered_map或其他类似的开源结构。我将 30-40 个字符字符串作为键值对插入,并注意到一个有趣的行为。第一次执行代码(Clion)时,花了 20 秒完成,我重复了测试(什么都不做),是 14 秒,然后又是 8 秒、4 秒,代码现在运行大约 3 秒。我应该重复一遍,我的代码中唯一昂贵的操作是批量 unordered_map insert,多线程与std::lock_guard<std::mutex>.

另一个重要的信息是我正在从文件中读取这些键和值。所以我想到了在Ubuntu 中发生的一些文件缓存。但是我用不同的机制做同样的事情,从来没有经历过这样的事情。然后我想到了一些 RAM 分配技巧,可以在程序结束后保持大部分地图完好无损。但我没有做任何事情来实现它。

为什么会这样?不仅如此,我该如何重置?我需要进行客观测试,因为我的代码将在多个服务器中运行,而无需任何预缓存。

谢谢。

tad*_*man 14

第一次运行代码时,它必须:

  • 如果磁盘转速下降或空闲,则唤醒磁盘
  • 从磁盘读取数据
  • 从磁盘读取可执行文件
  • 也可能加载一些共享库

第二次运行代码时,它可以:

  • 从内存中的操作系统读取缓存中读取数据
  • 从内存中的操作系统读取缓存读取可执行文件
  • 从内存中的操作系统读取缓存读取共享库
  • 由于负载不足,将 CPU 节流到更高的频率

这就是为什么多次长时间运行测试很重要,不仅仅是几秒钟,而是至少连续 10-15 分钟。

您的执行时间一开始会有很大差异,但稍后会收敛到更一致的值。您始终可以按运行时间排序并找到第 95 个百分位数,即程序在 95% 的时间内运行的时间。

  • 请注意,一旦程序部署在另一个硬件/环境上,所有测量结果都可能消失。 (5认同)
  • @idclev463035818 如果第一次运行时从慢速硬盘加载数据(可能是随机的),然后在下一次运行时从内存加载数据,则性能差异可能是 1 或 2 个数量级。实际上,数据甚至可以直接从 CPU 缓存加载,因此速度更快(由于吞吐量和较低的延迟)! (3认同)
  • @bolov 绝对。当您转向不同的硬件时,所有的赌注都会消失。您只能通过一个数据点(一台机器)获得一般意义。 (2认同)
  • @idclev463035818 当然可以,如果你的CPU处于低功耗状态,然后醒来为“turbo”。我在一些笔记本电脑上看到过这种情况,其中静态 CPU 约为 1GHz,睿频约为 4GHz。旋转的磁盘加上休眠的 CPU 意味着截然不同的时间。对于 I/O 受限的任务,差异可能更大,例如磁盘的 MB/s 与内存的 GB/s。 (2认同)