【发布时间】: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 < ARRAY_SIZE; j++) { sum += N_TIMES * array[j] }。摆脱for (i = 0...循环。当然,array没有初始化,所以你会得到零或其他什么。但我认为这不是您的代码的重点。 -
@Dante 你错过了一个明显的优化(由 information_interchange 推荐),但是你在展开循环和确定展开的最佳数字时遵循的过程是一个很好的技能,可以放在你的口袋里。总有一天,这样的技巧会对你非常有用。
-
您不使用此表或结果,因此任何编译时优化都会删除两个循环:)
标签: c optimization