【问题标题】:Why is a if statement and a variable declaration faster than a addition in a loop?为什么 if 语句和变量声明比循环中的加法更快?
【发布时间】:2017-07-25 01:19:48
【问题描述】:

如果我们有这样声明变量的 if 语句:

#include <iostream>
#include <ctime>

using namespace std;

int main() {

    int res = 0;

    clock_t begin = clock();
    for(int i=0; i<500500000; i++) {
        if(i%2 == 0) {int fooa; fooa = i;}
        if(i%2 == 0) {int foob; foob = i;}
        if(i%2 == 0) {int fooc; fooc = i;}
    }
    clock_t end = clock();
    double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;

    cout << elapsed_secs << endl;

    return 0;
}

结果是:

1.44

Process returned 0 (0x0)   execution time : 1.463 s
Press any key to continue.

但是,如果是的话:

#include <iostream>
#include <ctime>

using namespace std;

int main() {

    int res = 0;

    clock_t begin = clock();
    for(int i=0; i<500500000; i++) {
        res++;
        res--;
        res++;
    }
    clock_t end = clock();
    double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;

    cout << elapsed_secs << endl;

    return 0;
}

结果是:

3.098

Process returned 0 (0x0)   execution time : 3.115 s
Press any key to continue.

为什么加法或减法的运行时间比带有变量声明的 if 语句要长?

【问题讨论】:

  • 因为带有变量声明的 if 语句实际上什么都不做,因此它不存在。 E:虽然现在我看了一下,这些循环都没有做任何事情,所以为了得到任何经过的时间,你必须在编译时抑制优化。这使得结果毫无意义,但这也意味着我最初的猜测不适用。
  • 检查您的汇编代码以查看优化效果。
  • 当编译器因禁用优化而瘫痪时,查看生成的代码的运行时是没有用的。使用-O2/O2 重试。
  • 你的测试完全没有意义。编译器有权根据“as-if”规则完全消除第一个循环,无论是否指定优化。

标签: c++ loops


【解决方案1】:

几乎可以肯定,这种差异是由于编译器优化造成的。您必须查看程序集才能确定,但​​这是我对发生的事情的看法:

在第一个示例中,优化器很容易意识到ifs 的主体无效。在每个if 的局部变量中,声明、分配并立即销毁。所以ifs 被优化掉了,留下一个空的for 循环也被优化掉了。

第二个例子中的情况总体上并不是那么微不足道。 微不足道的是,循环体归结为单个res++,很可能会进一步优化为++res。但是因为res 不是循环的局部,优化器必须考虑整个main() 函数来实现循环无效。很可能它没有这样做。

结论:在目前的形式下,测量是没有意义的。禁用优化也无济于事,因为您永远不会为生产构建这样做。如果您真的想深入研究,我建议您观看CppCon 2015: Chandler Carruth "Tuning C++: Benchmarks, and CPUs, and Compilers! Oh My!",以获得有关如何在此类情况下处理优化器的重要建议。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-14
    • 1970-01-01
    • 1970-01-01
    • 2012-12-02
    • 1970-01-01
    相关资源
    最近更新 更多