当前位置: 首页 > 知识库问答 >
问题:

优化循环添加 [重复]

李俭
2023-03-14

我有一个任务来优化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];
            }

Im使用带有gcc-m32-STD = GNU 11-Wall-g a04 . c-o a04标志的gcc编译器,所有编译器优化都被关闭

共有2个答案

夏和雅
2023-03-14

您可以将变量“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”。

范翰池
2023-03-14

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

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

sum *= N_TIMES
 类似资料:
  • 问题内容: 我使用java for循环进行了一些运行时测试,并发现了一种奇怪的行为。对于我的代码,我需要原始类型(例如int,double等)的包装对象来模拟io和输出参数,但这不是重点。只是看我的代码。具有字段访问权限的对象如何比原始类型更快? 优先类型的循环: 结果: MicroTime原语(最大值:= 10000.0):110 MicroTime原语(最大值:= 100000.0):1081

  • 有时候你会遇到循环,或者递归函数,它们会花费很长的执行时间,可能是你的产品的瓶颈。在你尝试使循环变得快一点之前,花几分钟考虑是否有可能把它整个移除掉,有没有一个不同的算法?你可以在计算时做一些其他的事情吗?如果你不能找到一个方法去绕开它,你可以优化这个循环了。这是很简单的,move stuff out。最后,这不仅需要智慧而且需要理解每一种语句和表达式的开销。这里是一些建议: 删除浮点运算操作。

  • 我正在使用Wordpress标签在我的网站上创建特色文章部分(主页上显示了3篇最新的标记为“特色”的文章),代码如下: 每个条目都包裹着“特色文章”,但由于我希望第一个帖子是全宽的,其他2个半宽的,我想知道如何给它们添加合适的类?所以,第一个帖子得到“全宽度”类和另外两个“半宽度”... 如果我没有正确解释(英语不是第一语言)我道歉。 任何帮助都将不胜感激

  • 现在,当我尝试运行它时,结果是这样的:

  • 问题内容: 我在学校被告知,修改a的index变量是一种不好的做法: 范例: 有论据认为, 某些编译器优化可以优化循环, 而无需重新计算索引并限制每个循环。 我进行了一些测试,似乎默认情况下每次都会重新计算索引和绑定。 我想知道是否有可能在中激活这种功能? 例如,优化这种循环: 无需写: 这只是一个例子,我很想尝试一下改进。 编辑 根据Peter Lawrey的回答, 为什么在这个简单的示例中JV

  • 问题内容: 我听说Java支持“循环取消切换”,因此我只是在JMH中对其进行了测试。 我认为在JIT之后它们将完全相同。为什么是这样? 检测结果 测试环境 问题答案: JMH禁用方法的内联。非内联方法是JVM的黑匣子- 编译器不知道该方法是否会修改字段,引发异常,将其注册为垃圾等。JIT编译器无法在此类方法调用中应用许多优化。(想象一下,黑盒方法使用反射来修改字段,因此循环取消切换将变得无效)。