【问题标题】:optimizing for loop addition [duplicate]优化循环添加[重复]
【发布时间】:2018-01-31 07:11:34
【问题描述】:

我有一个优化 for 循环的任务,以便编译器编译运行速度更快的代码。目标是让代码在 5 秒或更短的时间内运行,原始运行时间约为 23 秒。原始代码如下所示:

#include <stdio.h>
#include <stdlib.h>

#define N_TIMES     600000
#define ARRAY_SIZE   10000

int main(void)
{
    double  *array = calloc(ARRAY_SIZE, sizeof(double));
    double  sum = 0;
    int     i;

    printf("CS201 - Asgmt 4 - I. Forgot\n");

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

        int     j;

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

        }

    return 0;
}

我的第一个想法是在内部 for 循环上进行循环展开,将其缩短到 5.7 秒,该循环看起来像这样:

 for (j = 0; j < ARRAY_SIZE - 11; j+= 12) {
            sum = sum + (array[j] + array[j+1] + array[j+2] + array[j+3] + array[j+4] + array[j+5] + array[j+6] + array[j+7] + array[j+8] + array[j+9] + array[j+10] + array[j+11]);
                }

在每个循环中将其取出到阵列中的 12 个点后,性能不再提高,所以我的下一个想法是尝试引入一些并行性,所以我这样做了:

   sum = sum + (array[j] + array[j+1] + array[j+2] + array[j+3] + array[j+4] + array[j+5]);
   sum1 = sum1 + (array[j+6] + array[j+7] + array[j+8] + array[j+9] + array[j+10] + array[j+11]);

这实际上最终减慢了代码的速度,并且每个额外的变量都会再次减慢代码的速度。我不确定并行性是否在这里不起作用,或者我是否实施错误或什么但不起作用,所以现在我不确定如何再优化它以使其低于 5 秒。

编辑:我忘了提到我不能对外部循环进行任何更改,只能对内部循环进行任何更改

EDIT2:这是我正在尝试为我的作业优化的代码部分:

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

我正在使用带有标志的 gcc 编译器 gcc -m32 -std=gnu11 -Wall -g a04.c -o a04 关闭所有编译器优化

【问题讨论】:

  • 您的array 全部为零。并且程序没有任何输出。所以优化的程序将是空的。更新:抱歉,它实际上应该打印“CS201 - Asgmt 4 - I. Forgot\n”...
  • 是什么让您认为“并行”代码中有任何并行性?
  • 你不需要外部的i 循环,因为它只是重复添加。 for (j = 0; j &lt; ARRAY_SIZE; j++) { sum += N_TIMES * array[j] }。摆脱for (i = 0... 循环。当然,array 没有初始化,所以你会得到零或其他什么。但我认为这不是您的代码的重点。
  • @Dante 你错过了一个明显的优化(由 information_interchange 推荐),但是你在展开循环和确定展开的最佳数字时遵循的过程是一个很好的技能,可以放在你的口袋里。总有一天,这样的技巧会对你非常有用。
  • 您不使用此表或结果,因此任何编译时优化都会删除两个循环:)

标签: c optimization


【解决方案1】:

既然 j 和 i 互不依赖,我想你可以这样做:

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

sum *= N_TIMES

【讨论】:

  • 这应该会减少运行时间 ~600.000 倍。
  • 我应该提到我只能对内部循环进行更改,而不是对外部循环进行更改。
  • 嗯,所以出于某种原因需要外循环?
  • @DanteKiaunis:你应该提到这一点,是的。现在你的问题更没有意义了。请发布您尝试优化的实际代码。
  • 我要优化的代码是我提交的第一个代码......这是一个家庭作业,它不应该是有用的或任何东西
【解决方案2】:

您可以像这样将变量“j”的声明移出循环:

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

    //int     j; <-- Move this line out of the loop
    for (j = 0; j < ARRAY_SIZE - 11; j+= 12) {
        sum = sum + (array[j] + array[j+1] + array[j+2] + array[j+3] + array[j+4] + array[j+5] + array[j+6] + array[j+7] + array[j+8] + array[j+9] + array[j+10] + array[j+11]);
    }
 }

您不需要在每次循环运行时声明一个新变量“j”。

【讨论】:

  • 这不太可能影响性能。
猜你喜欢
  • 2012-03-10
  • 2019-02-19
  • 2012-02-06
  • 1970-01-01
  • 2020-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多