[英]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.1 , gcc 5.3和icc 13.0.1似乎無法進行這樣的優化,即使使用-Ofast
。 (請注意編譯器之間生成的程序集如何大不相同!)。 但是,當從等式中刪除mul2
和x2
, clang能夠執行類似的優化,即使使用-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的答案中的一部分,並且當你從表達式中刪除x2
和mul2
時,clang會執行優化。
編譯器可以優化它可以做的所有事情。 但我也認為優化編譯器已經是龐大而復雜的程序,其中錯誤會產生很大的后果,因為它們幾乎是其他所有東西的基礎(Python最新的解釋器是用...編寫的)
因此,優化器的效率與其復雜性之間必須保持平衡,而且我認為這個示例程序超出了gcc的范圍,而且只是針對clang。 沒有什么能阻止他們進行優化,除非它對於那些編譯器的當前版本來說太復雜了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.