簡體   English   中英

為什么這個程序沒有被優化掉?

[英]Why is this program not optimized away?

考慮以下簡單程序(改編自此問題 ):

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

我相信它在功能上等同於以下一個:

#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.1gcc 5.3icc 13.0.1似乎無法進行這樣的優化,即使使用-Ofast (請注意編譯器之間生成的程序集如何大不相同!)。 但是,當從等式中刪除mul2x2clang能夠執行類似的優化,即使使用-O2

是什么阻止了兩個編譯器將第一個程序優化到第二個程序?

即使對於鏗鏘,完整的表達也太復雜了。 如果拆分它,那么一切都會再次優化:

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

我不是編譯器程序員,所以這只能是猜測。 恕我直言,答案是@dlask的答案中的一部分,並且當你從表達式中刪除x2mul2時,clang會執行優化。

編譯器可以優化它可以做的所有事情。 但我也認為優化編譯器已經是龐大而復雜的程序,其中錯誤會產生很大的后果,因為它們幾乎是其他所有東西的基礎(Python最新的解釋器是用...編寫的)

因此,優化器的效率與其復雜性之間必須保持平衡,而且我認為這個示例程序超出了gcc的范圍,而且只是針對clang。 沒有什么能阻止他們進行優化,除非它對於那些編譯器的當前版本來說太復雜了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM