运行 时间函数的非线性行为
Nonlinear behavior of function run time
我有一个计算总和的函数,并根据总和的结果执行特定任务或给出警告消息。我需要在粒子轨迹模拟中 运行 这个函数数百万次(它计算时间和位置相关的力)并注意到我的代码非常慢。
这是我的 MWE:
#include <stdio.h>
#include <math.h>
int foo()
{
double sum =0;
double dummy_sum = 0;
for (size_t i=0; i<40; i++)
{
sum+=1e-2;
dummy_sum += 1e-2;
}
if (sum>5.) // normally this should not happen
{
printf("warning message!\n");
return(-1);
}
else if(sum >0)
{
// normal behavior
}
return(0);
}
int main()
{
int fooint;
for(size_t i=0; i<5e9; i++)
{
fooint = foo();
if(fooint!=0)
{
return(fooint);
}
}
return 0;
}
我使用 gcc 4.8.5 版 gcc -Ofast -std=c99 test.c -o test.exe
进行编译。
为了找到优化我的功能的方法,我 运行 time ./test.exe
表明 运行 在我的机器上的时间约为 38 秒。
当我删除线时
printf("warning message!\n");
return(-1);
或行
sum+=1e-2;
运行时间减少到大约 6 秒。
另外,当我将函数循环中的迭代次数更改为 35 时,速度提高了,运行 时间为 6 秒。将其增加到 36 会得到 运行 33 秒的时间。
我在具有相同 linux 和 gcc 版本的另一台机器上编译并 运行 代码并得到相似的结果(运行 时间稍长,因为机器较旧) .
什么可能导致这种 st运行ge 行为?
这不是什么奇怪的行为。
如果删除 printf
和 return(-1)
行,那么函数 foo
将由编译器优化,并且将只是其中代码的 return(0);
none执行,因为结果不会改变。如果您注释代码 sum+=1e-2;
,也会发生同样的情况,编译器知道该函数唯一可能的结果是 return(0);
,sum
被初始化为 0 并且永远不会改变。
这是一个 GCC 错误。 Clang 正确优化您的代码
foo: # @foo
xor eax, eax
ret
main: # @main
xor eax, eax
ret
在接近零的 运行 时间。
我有一个计算总和的函数,并根据总和的结果执行特定任务或给出警告消息。我需要在粒子轨迹模拟中 运行 这个函数数百万次(它计算时间和位置相关的力)并注意到我的代码非常慢。
这是我的 MWE:
#include <stdio.h>
#include <math.h>
int foo()
{
double sum =0;
double dummy_sum = 0;
for (size_t i=0; i<40; i++)
{
sum+=1e-2;
dummy_sum += 1e-2;
}
if (sum>5.) // normally this should not happen
{
printf("warning message!\n");
return(-1);
}
else if(sum >0)
{
// normal behavior
}
return(0);
}
int main()
{
int fooint;
for(size_t i=0; i<5e9; i++)
{
fooint = foo();
if(fooint!=0)
{
return(fooint);
}
}
return 0;
}
我使用 gcc 4.8.5 版 gcc -Ofast -std=c99 test.c -o test.exe
进行编译。
为了找到优化我的功能的方法,我 运行 time ./test.exe
表明 运行 在我的机器上的时间约为 38 秒。
当我删除线时
printf("warning message!\n");
return(-1);
或行
sum+=1e-2;
运行时间减少到大约 6 秒。
另外,当我将函数循环中的迭代次数更改为 35 时,速度提高了,运行 时间为 6 秒。将其增加到 36 会得到 运行 33 秒的时间。
我在具有相同 linux 和 gcc 版本的另一台机器上编译并 运行 代码并得到相似的结果(运行 时间稍长,因为机器较旧) .
什么可能导致这种 st运行ge 行为?
这不是什么奇怪的行为。
如果删除 printf
和 return(-1)
行,那么函数 foo
将由编译器优化,并且将只是其中代码的 return(0);
none执行,因为结果不会改变。如果您注释代码 sum+=1e-2;
,也会发生同样的情况,编译器知道该函数唯一可能的结果是 return(0);
,sum
被初始化为 0 并且永远不会改变。
这是一个 GCC 错误。 Clang 正确优化您的代码
foo: # @foo
xor eax, eax
ret
main: # @main
xor eax, eax
ret
在接近零的 运行 时间。