【问题标题】:How to reduce the overhead of loop when measuring the performance?在测量性能时如何减少循环的开销?
【发布时间】:2015-01-27 15:31:11
【问题描述】:

当我尝试衡量一段代码的性能时,我将它放入一个循环并迭代一百万次。

for i: 1 -> 1000000
{
    "test code"
}

但是通过使用分析工具,我发现循环的开销如此之大,以至于它对性能结果的影响很大,尤其是当一段代码很小时,比如 1.5s 的总运行时间和 0.5s 的循环开销。

所以我想知道是否有更好的方法来测试性能?还是我应该坚持这种方法,但在同一个循环下制作多段相同的代码以增加其在性能上的权重?

for i: 1 -> 1000000
{
    "test code copy 1"
    "test code copy 2"
    "test code copy 3"
    "test code copy 4"
}

或者可以从总时间中减去循环开销吗?非常感谢!

【问题讨论】:

  • 一个好的编译器会在某种程度上展开循环。您对什么样的任务进行基准测试?
  • @E_net4 我正在测试表达式模板。我检查了程序集,但发现即使表达式很小,比如 A+B,它也没有展开。
  • 您使用的是什么编译器,您尝试过哪些标志?
  • @E_net4 我正在使用带有“-Wall -g -O2(or-O3) -std=c++11”标志的 gcc 4.8.3。
  • 由于现代处理器的速度,我建议使用 1.0E+09 迭代。还要记住,还有其他事情可能会妨碍您的分析:其他程序正在执行、等待 I/O、内存或数据总线共享。

标签: c++ performance profiling


【解决方案1】:

您需要查看编译器生成的程序集列表。计算开销中的指令数。

通常,对于递增循环,开销包括:

  1. 循环计数器递增。
  2. 跳到循环顶部。
  3. 计数器与限制的比较。

在许多处理器上,这些都是一条或接近一条处理器指令。因此,找出一条指令退出的平均时间,乘以开销中的指令数,这就是一次迭代的开销时间。

例如,在平均每条指令 100ns 和 3 条指令开销的处理器上,每次迭代使用 3 * (100ns) 或每次迭代 300ns。给定 1.0E6 次迭代,3.0E08 纳秒将归因于开销。从您的测量中减去这个数量,以便更准确地测量循环的内容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-13
    • 2014-04-10
    • 1970-01-01
    • 1970-01-01
    • 2017-05-07
    • 2012-05-12
    • 2014-03-05
    • 1970-01-01
    相关资源
    最近更新 更多