簡體   English   中英

C中的循環優化

[英]Loop Optimization in C

我的任務是優化C中的特定for循環。這是循環:

#define ARRAY_SIZE 10000
#define N_TIMES    600000

for (i = 0; i < N_TIMES; i++)
{
    int j;

    for (j = 0; j < ARRAY_SIZE; j++)
    {
        sum += array[j];
    }
}

我應該使用循環展開,循環拆分和指針來加速它,但每次我嘗試實現某些東西時,程序都不會返回。 這是我到目前為止所嘗試的:

for (i = 0; i < N_TIMES; i++) 
{
    int j,k;

    for (j = 0; j < ARRAY_SIZE; j++) 
    {    
        for (k = 0; k < 100; k += 2) 
        {
            sum += array[k];
            sum += array[k + 1];
        }
    } 
}

我不明白為什么程序現在甚至沒有返回。 任何幫助,將不勝感激。

第二段代碼既低效錯誤,因為它增加了比原始代碼更多的值。

循環展開(或者在這種情況下減少,因為你可能不想展開一萬次迭代循環)將是:

// Ensure ARRAY_SIZE is a multiple of two before trying this.
for (int i = 0; i < N_TIMES; i++)
    for (int j = 0; j < ARRAY_SIZE; j += 2)
        sum += array[j] + array[j+1];

但是,說實話,愚蠢的編譯器的時代早已過去。 您通常應將此級別的微優化保留在編譯器中,而您則專注於更高級別的內容,如數據結構,算法和人工分析。

最后一個是相當重要的。 由於您將相同的數組添加到累計和中的次數相同,因此您只需要一次數組的總和然后您可以根據需要多次添加該部分和:

int temp = 0;
for (int i = 0; i < ARRAY_SIZE; i++)
    temp += array[i];
sum += temp * N_TIMES;

它仍然O(n)但在低得多的乘數n (一個而不是六十萬)。 可能是因為gcc的瘋狂優化級別-O3可以解決這個問題,但我對此表示懷疑。 人腦在很多領域仍然可以超越計算機。

現在,無論如何:-)

你的程序沒有任何問題...它會返回。 它只需要比第一個多50倍...

在第一個你有2個fors:600.000 * 10.000 = 6.000.000.000迭代。

在第二個你有3個fors:600.000 * 10.000 * 50 = 300.000.000.000迭代......

循環展開不會加速循環,它會減慢它們的速度。 在過去,它通過減少條件評估的數量為您提供了減速。 在現代,它通過殺死緩存來減慢你的速度。

這里沒有明顯的循環拆分用例。 要分割循環,您需要在迭代中查找兩個或更多明顯的分組。 在一段時間你可以將array[j]乘以i而不是做外循環並聲稱你已經將內部與外部分開,然后將外部丟棄為無用。

C數組索引語法只是定義為(一種特殊的語法)指針算法。 但我想你想要的東西是這樣的:

sum += *arrayPointer++;

代替你使用j ,適當地初始化的東西。 但我懷疑你會從中獲得什么。

根據評論,如果這是真實的生活,那么你只需讓編譯器弄清楚這些東西。

暫無
暫無

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

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