简体   繁体   English

为什么这个程序没有被优化掉?

[英]Why is this program not optimized away?

Consider the following, simple program (adapted from this question ): 考虑以下简单程序(改编自此问题 ):

#include <cstdlib>

int main(int argc, char** argv) {
    int mul1[10] = { 4, 1, 8, 6, 3, 2, 5, 8, 6, 7 }; // sum = 50
    int mul2[10] = { 4, 1, 8, 6, 7, 9, 5, 1, 2, 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;
}

I believe it is functionally equivalent to the following one: 我相信它在功能上等同于以下一个:

#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;
}

And yet clang 3.7.1 , gcc 5.3 and icc 13.0.1 seem to be unable to make such optimization, even with -Ofast . 然而clang 3.7.1gcc 5.3icc 13.0.1似乎无法进行这样的优化,即使使用-Ofast (Note by the way how the generated assembly is vastly different between compilers!). (请注意编译器之间生成的程序集如何大不相同!)。 However, when removing mul2 and x2 from the equation, clang is able to perform a similar optimization, even with -O2 . 但是,当从等式中删除mul2x2clang能够执行类似的优化,即使使用-O2

What prevents both compilers from optimizing the first program into the second? 是什么阻止了两个编译器将第一个程序优化到第二个程序?

The complete expression is too complicated even for clang. 即使对于铿锵,完整的表达也太复杂了。 If you split it then everything gets optimized again: 如果拆分它,那么一切都会再次优化:

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);

I'm not a compiler programmer so this can only be a guess. 我不是编译器程序员,所以这只能是猜测。 IMHO, the answer is part in @dlask's answer and part in the remark that clang does the optimisation when you remove x2 and mul2 from the expression. 恕我直言,答案是@dlask的答案中的一部分,并且当你从表达式中删除x2mul2时,clang会执行优化。

The compiler may optimize away all that it can do. 编译器可以优化它可以做的所有事情。 But I also think that optimizing compilers are already huge and complicated programs, in which bugs can have high consequences because they are at the base of almost everything else (Python most current interpreter is written in ... C) 但我也认为优化编译器已经是庞大而复杂的程序,其中错误会产生很大的后果,因为它们几乎是其他所有东西的基础(Python最新的解释器是用...编写的)

So there must be a balance between the efficiency of the optimizer and its complexity, and I think that this example program is beyond it for gcc, and just around for clang. 因此,优化器的效率与其复杂性之间必须保持平衡,而且我认为这个示例程序超出了gcc的范围,而且只是针对clang。 Nothing prevents them to do that optimization except that it is just too complicated for current version of those compilers. 没有什么能阻止他们进行优化,除非它对于那些编译器的当前版本来说太复杂了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM