Hãy xem xét những điều sau đây, chương trình đơn giản (chuyển thể từ this question):Tại sao chương trình này không được tối ưu hóa?
#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;
}
Tôi tin rằng nó có chức năng tương đương với một sau:
#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;
}
Tuy nhiên clang 3.7.1, gcc 5.3 và icc 13.0.1 dường như là không thể để thực hiện tối ưu hóa như vậy, ngay cả với -Ofast
. (Lưu ý bằng cách làm thế nào lắp ráp được tạo ra là rất khác nhau giữa các trình biên dịch!). Tuy nhiên, khi xóa mul2
và x2
khỏi phương trình, clang có thể thực hiện tối ưu hóa tương tự, ngay cả với -O2
.
Điều gì ngăn cản cả hai trình biên dịch tối ưu hóa chương trình đầu tiên vào chương trình thứ hai?
@buttiful buttefly Trong trường hợp hoạt động chung x1 * mul1 [i] có thể dẫn đến tràn, –
Tôi ngạc nhiên rằng clang có thể tối ưu hóa vòng lặp khi bạn loại bỏ 'x2 * mul2 [i]' khỏi phương trình. Cá nhân tôi cảm thấy rằng người ta không nên mong đợi bất cứ điều gì từ trình tối ưu hóa trình biên dịch; bất cứ điều gì được nhận là tiền thưởng! – iammilind
@vlad tràn là UB, vì vậy có thể được coi là không xảy ra khi tối ưu hóa. – Yakk