最终赋值的 C 循环优化帮助(禁用编译器优化)

标签 c loops optimization compiler-optimization debug-mode

因此,对于我在计算机系统类(class)中的最终作业,我们需要优化这些 for 循环,使其比原始循环更快。

使用我们的 linux 服务器,基本等级在 7 秒以下,完整等级在 5 秒以下。我在这里的这段代码大约需要 5.6 秒。我想我可能需要以某种方式使用指针来让它运行得更快,但我不太确定。任何人都可以提供我有的任何提示或选项吗?

该文件必须保持在 50 行或更少,我将忽略教师包含的那些注释行。

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

// You are only allowed to make changes to this code as specified by the comments in it.

// The code you submit must have these two values.
#define N_TIMES     600000
#define ARRAY_SIZE   10000

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

    // You can add variables between this comment ...
    register double sum1 = 0, sum2 = 0, sum3 = 0, sum4 = 0, sum5 = 0, sum6 = 0, sum7 = 0, sum8 = 0, sum9 = 0;
    register int j;
    // ... and this one.

    printf("CS201 - Asgmt 4 - \n");

    for (i = 0; i < N_TIMES; i++)
    {
        // You can change anything between this comment ...
        for (j = 0; j < ARRAY_SIZE; j += 10)
        {
            sum += array[j];
            sum1 += array[j + 1];
            sum2 += array[j + 2];
            sum3 += array[j + 3];
            sum4 += array[j + 4];
            sum5 += array[j + 5];
            sum6 += array[j + 6];
            sum7 += array[j + 7];
            sum8 += array[j + 8];
            sum9 += array[j + 9];
        }
        // ... and this one. But your inner loop must do the same
        // number of additions as this one does.
    }                   

    // You can add some final code between this comment ...
    sum += sum1 + sum2 + sum3 + sum4 + sum5 + sum6 + sum7 + sum8 + sum9;
    // ... and this one.

    return 0;
}

最佳答案

您可能在正确的轨道上,尽管您需要对其进行测量才能确定(我通常建议测量,而不是猜测在这里似乎有点多余,因为作业的重点是测量)。

优化编译器可能不会看到太大的区别,因为它们对这类东西非常聪明,但是,由于我们不知道它将在什么优化级别进行编译,因此您可能会得到实质性的改进。

在内部循环中使用指针是一个简单的事情,首先添加一个指针变量:

register double *pj;

然后将循环更改为:
for (pj = &(array[0]); pj < &(array[ARRAY_SIZE]); j++) {
        sum += *j++;
        sum1 += *j++;
        sum2 += *j++;
        sum3 += *j++;
        sum4 += *j++;
        sum5 += *j++;
        sum6 += *j++;
        sum7 += *j++;
        sum8 += *j++;
        sum9 += *j;
    }

这使循环中的加法数量保持不变(当然,假设您将 +=++ 计算为加法运算符),但基本上使用指针而不是数组索引。

在我的系统上没有优化 1 的情况下,它从 9.868 秒(CPU 时间)下降到 4.84 秒。您的里程可能会有所不同。

1 优化级别 -O3 ,两者都被报告为需要 0.001 秒,因此,如上所述,优化器非常聪明。但是,鉴于您看到的时间超过 5 秒,我建议它没有经过优化编译。

顺便说一句,这是一个很好的理由,为什么通常建议以可读的方式编写代码并让编译器负责让它运行得更快。虽然我在优化方面的微薄尝试使速度大致翻了一番,但使用 -O3使其运行速度快了一万倍:-)

关于最终赋值的 C 循环优化帮助(禁用编译器优化),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32000917/

相关文章:

c - 一个进程是否可以在运行时更改另一个进程中的变量值?

c - OpenSSL X509_Sign "invalid digital signature"

sql-server - 如何分离变量和值,然后插入表中?

java - 将列表从 Java 返回到 Freemarker

arrays - 双和优化

c - 如何通过指针打印数组的元素?

编译器不会在函数参数不匹配时发出错误/警告

python - 嵌套while循环绘制图案

java - 如何优化我的代码以将给定索引范围的数组元素与相关元素交换?

php - 优化 jQuery 速度