【问题标题】:Why is C++ unnecessary loop making program faster?为什么 C++ 不必要的循环使程序更快?
【发布时间】:2013-08-16 19:35:03
【问题描述】:

我在一些竞争性的编程网站上练习,比如UVaLOj,并注意到有好几次(10 次或更多!)在我的程序中放置了一个不必要的循环,例如,将它放在开头程序-

for (int _delay = 0; _delay < 500000000; _delay++ );

让它比平常跑得更快(!),并给我更好的排名。我一遍又一遍地重新提交,但这种情况一直在发生。 我的问题是这怎么可能?只是巧合(发生了很多次)还是编译后的程序由于某种原因得到了优化?

【问题讨论】:

  • 如果您想知道,我曾经写过一个延迟函数,但在第一次发生这种情况时,我在程序开始时错误地调用了它。
  • 您可以通过比较带有和不带有该循环的机器代码来解决大多数优化问题。
  • 好吧,这有点奇怪,但我可以看到改变一些启发式的值,最终可能会使编译器以不同的方式编译它。看看汇编代码就知道了。
  • 顺便说一句,如果你第一次和第二次提交给 UVa 的时间间隔很长(例如,超过一年),请记住 UVa 会不断升级他们的系统,所以你的第二次尝试肯定会运行即使代码相同,也比第一次尝试更快。
  • @keelar 我已经在几分钟内重新提交了那些带有和不带有 for 循环的代码。

标签: c++ visual-c++ compiler-optimization


【解决方案1】:

我认为大多数编译器都会忽略您提到的以下语句:

for (int _delay = 0; _delay < 500000000; _delay++ );

因为for循环只是修改了一个局部变量,而这个变量的作用域只存在于for循环中。

至于上面的说法让整个程序更快……我不认为它可以……

【讨论】:

  • 编译器是否有可能忽略此代码段并在编译时触发优化?
  • 可能有这种可能性,但我认为这不适用于一般情况......
  • 是的,这很奇怪。自从发布这个问题以来,我已经检查了我的其他几个解决方案的案例。这种时间差异仍然存在!
  • @user1362452:这个区别有多大?有统计学意义吗?你能给出一个有和没有的装配清单吗?
  • 那么唯一的办法就是尝试获取UVa使用的编译器并比较它们的二进制文件...
【解决方案2】:

假设这样一个无用的循环对编译后的代码有任何影响,性能差异的一个来源可能是分支指令落入不同的桶中,从而使 CPU 中的分支预测更加准确(参见 Why would introducing useless MOV instructions speed up a tight loop in x86_64 assembly?)。但是,您必须在受控环境中运行程序才能进行适当的测试;我不会相信在线评委所做的测量。

【讨论】:

    猜你喜欢
    • 2017-04-16
    • 2020-12-25
    • 2020-05-11
    • 1970-01-01
    • 2017-03-08
    • 1970-01-01
    • 1970-01-01
    • 2011-02-08
    • 1970-01-01
    相关资源
    最近更新 更多