C中的循环优化

时间:2014-06-10 04:57:33

标签: c loops optimization

我的任务是在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];
        }
    } 
}

我不明白为什么程序现在甚至没有返回。任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:8)

第二段代码效率低下错误,因为它增加了比原始代码更多的值。

循环展开(或者在这种情况下减少,因为你可能不想展开一万次迭代循环)将是:

// 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可以解决这个问题,但我对此表示怀疑。在很多领域,人类大脑仍然可以超越计算机。

现在,无论如何: - )

答案 1 :(得分:3)

你的程序没有任何问题......它会返回。它只需要比第一个多50倍......

首先你有2个人:600.000 * 10.000 = 6.000.000.000次迭代。

第二个你有3个:600.000 * 10.000 * 50 = 300.000.000.000次迭代...

答案 2 :(得分:1)

循环展开不会加速循环,会减慢它们的速度。在过去,它通过减少条件评估的数量为您提供了减速。在现代,它通过杀死缓存来减慢你的速度。

此处没有明显的循环拆分用例。要分割循环,您需要在迭代中查找两个或更多明显的分组。在一段时间内,您可以将array[j]乘以i,而不是做外圈并声称您已将内部与外部分开,然后将外部丢弃为无用。

C数组索引语法只是定义为(一种特殊的语法)指针算法。但我猜你想要的东西是:

sum += *arrayPointer++;

取代您对j的使用,适当地初步化。但是我怀疑你从中获得了什么。

根据评论,如果这是现实生活,那么你只需让编译器把这些东西搞清楚。