簡體   English   中英

g ++ -O優化

[英]g++ -O optimizations

我有以下代碼:

#include <iostream>
int main()
{
        int n = 100;
        long a = 0;
        int *x = new int[n];

        for(int i = 0; i < n; ++i)
                for(int j = 0; j < n; ++j)
                        for(int k = 0; k < n; ++k)
                                for(int l = 0; l < n; ++l)
                                {   

                                        a += x[(j + k + l) % 100];
                                }   
        std::cout << a << std::endl;
        delete[] x;
        return 0;
}

如果我在沒有優化的情況下編譯g ++ test.cc然后運行時間./a.out它將顯示0.7s。 但是當我用-O編譯它時,時間減少了2倍。

編譯器使用

g++ (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2

我的問題

我如何重寫代碼,以便在沒有-OI的情況下進行編譯可以獲得相同的時間(或接近它)? 換句話說, 如何手動優化嵌套循環

為什么我問

我有一個類似的代碼,如果我使用-O優化,運行速度大約快4倍。

PS:我已經查看了編譯器的手冊,但是有太多的標志來測試哪一個確實有所不同。

此代碼具有未定義的行為,因此實際上優化器可以執行任何操作。

a += x[j + k + l % 100];

應該:

a += x[(j + k + l) % 100];

如果你解決了這個問題,我仍然不明白你為什么要優化實際上什么都不做的事情......

我個人會優化這個::)

std::cout << 0 << std::endl;

注意:刪除i的循環並執行std::cout << a * n << std::endl;

編譯器使用-O優化的大部分內容都是低於C ++的級別。 例如,所有變量都存在於內存中,包括循環變量。 因此,如果沒有優化,編譯器很可能會在內部循環的每次迭代中首先讀取循環變量以將其與0進行比較,在循環內部再次加載它以便將其用於索引,然后在循環結束時將再次讀取該值,遞增它並將其寫回。 通過優化,它會注意到循環體中的循環變量沒有改變,因此不需要每次都從內存中重新讀取。 此外,它還會注意到變量的地址永遠不會被采用,因此沒有其他代碼可以訪問它,因此也可以省略將其寫入存儲器。 也就是說,循環變量將僅存在於內存中。 僅執行此優化將在執行函數期間節省三億次內存讀取和一億次內存寫入。 但是由於處理器寄存器和內存讀/寫之類的東西沒有在語言級別公開,因此無法在語言級別對其進行優化。

此外,手動優化編譯器優化的東西是沒有意義的。 最好把時間花在優化編譯器無法優化的事情上。

您可以觀察到,您的循環形成一組系數coeff[i] ,使得對a[i] * coeff[i]求和a[i] * coeff[i]單個循環產生與嵌套循環相同的總數。 如果我們假設您的索引意味着(i + j + k) % 100則所有i coeff[i] = n * n * n ,因此您的整個程序簡化為

long coeff = n * n * n;
for (int i = 0; i < n; ++n)
    a += x[i] * coeff;

我肯定會在不到0.7秒的時間內完成。

你正在使用多項式時間算法( n ** 4 ),因此它很慢,特別是對於較大的n 也許復雜度較低的算法可以幫到你?

如果您希望優化代碼,可以要求編譯器為您進行優化,或者只是用匯編語言編寫並完成它。 不要試圖猜測C ++編譯器。

我如何重寫代碼,以便在沒有-OI的情況下進行編譯可以獲得相同的時間(或接近它)? 換句話說,如何手動優化嵌套循環?

你在匯編中寫下它們。 你好運,順便說一句。

編譯器中優化開關的目的是讓你說,“編譯器,我希望你嘗試生成快速組裝。” 默認情況下,編譯器不進行優化,因為這些優化可能會抑制生成的代碼的可調試性。 所以你必須特別要求他們。

一般來說,編譯器優化代碼所做的事情不是你可以手動完成的。 有些可以(比如循環展開),但其他人不可能。

暫無
暫無

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

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