索引 2^21 处的执行时间开销

Execution time overhead at index 2^21

我想做什么?

我写了一个程序,它从二进制文件中读取数据并根据读取的值进行计算。执行时间对于这个程序来说是最重要的。为了验证我的程序是否在指定的时间限制内运行,我尝试通过将所有计算存储在 std::vector<std::string> 中来 [=​​33=]log。在时间关键执行完成后,我将此向量写入文件。

向量中存储了什么?

在向量中我写了执行时间(std::chrono:steady_clock.now())和当前时钟时间(std::chrono::system_clock::now() 和 date.h by Howard Hinnant)。

我观察到了什么?

在分析结果时,我偶然发现了以下模式。独立于输入数据,一个操作的平均执行时间为 0.003 毫秒,在一个特定的可重现指数下,单个操作的平均执行时间激增至约 20 毫秒。在此之后,所有操作的执行时间回到 0.003ms。执行时间爆炸的指标是每次2097151。由于 2^21 等于 2097152,因此在 2^21 处发生了某些事情,这会减慢整个程序的速度。使用 2^22 和 2^23 可以观察到相同的效果。更有趣的是延迟加倍(2^21 = ~20ms,2^22 = ~43ms,2^23 =~81ms)。我用谷歌搜索了这个特定的数字,我唯一找到的是一些 node.js stuff,它在后台使用 c++。

我怀疑什么?

在索引 2^21 处必须扩展内存区域,这就是延迟发生的原因。

问题

  1. 我的假设是否正确,向量的大小是否有问题?
  2. 如何调试这种现象? (可以肯定的是,纯粹的向量是问题)
  3. 我可以预先分配足够的内存以避免内存膨胀吗?
  4. 除了支持 > 10.000.000.000 个元素的 std::vector,我可以使用什么?

我能够通过在程序的时间关键部分之前使用 std::vector::reserve() 预留内存来解决我的问题。感谢大家的评论。

这里是我使用的工作代码:

std::vector<std::string> myLogVector;
myLogVector.reserve(12000000);
//...do time critical stuff, without reallocating storage