c – 为什么这个程序没有优化?

考虑以下,简单的程序(从 this question改编):
#include <cstdlib>

int main(int argc,char** argv) {
    int mul1[10] = { 4,1,8,6,3,2,5,7 }; // sum = 50
    int mul2[10] = { 4,7,9,3 }; // sum = 46

    int x1 = std::atoi(argv[1]);
    int x2 = std::atoi(argv[2]);

    int result = 0;

    // For each element in mul1/mul2,accumulate the product with x1/x2 in result
    for (int i = 0; i < 10; ++i) {
        result += x1 * mul1[i] + x2 * mul2[i];
    }

    return result;
}

我相信它在功能上等同于以下内容

#include <cstdlib>

int main(int argc,char** argv) {
    int x1 = std::atoi(argv[1]);
    int x2 = std::atoi(argv[2]);

    return x1 * 50 + x2 * 46;
}

clang 3.7.1,gcc 5.3icc 13.0.1似乎无法做出这样的优化,即使使用-Ofast. (注意生成的程序集在编译器之间有很大的不同)!然而,当从等式中删除mul2和x2时,即使使用-O2,clang也能执行类似的优化.

什么阻止编译器将第一个程序优化到第二个程序?

解决方法

完整的表达对于cl is来说太复杂了.如果你拆分它,那么所有的东西再次被优化:
int result1 = 0;
int result2 = 0;

for (int i = 0; i < 10; ++i) {
    result1 += x1 * mul1[i];
    result2 += x2 * mul2[i];
}

std::cout << (result1 + result2);

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...