我有一个任务来优化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编译器,所有编译器优化都被关闭
您可以将变量“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”。
既然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编译器无法在此类方法调用中应用许多优化。(想象一下,黑盒方法使用反射来修改字段,因此循环取消切换将变得无效)。