C 函数运行时的非线性行为
我有一个计算总和的函数,根据总和的结果执行特定任务或发出警告消息。我需要在粒子轨迹模拟中运行此函数数百万次(它计算与时间和位置相关的力),并注意到我的代码非常慢 这是我的MWE:C 函数运行时的非线性行为,c,optimization,timing,C,Optimization,Timing,我有一个计算总和的函数,根据总和的结果执行特定任务或发出警告消息。我需要在粒子轨迹模拟中运行此函数数百万次(它计算与时间和位置相关的力),并注意到我的代码非常慢 这是我的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
#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;
}
还是排队
sum+=1e-2;
运行时间缩短到6秒左右
另外,当我将函数循环中的迭代次数更改为35次时,速度提高了,运行时间为6s。如果将其增加到36,则运行时间为33秒
我用相同的linux和gcc版本在不同的机器上编译并运行了代码,得到了类似的结果(随着机器的老化,运行时间稍长)
是什么导致了这种奇怪的行为?这不是一种奇怪的行为。
如果删除行
printf
和return(-1)
,则编译器将优化函数foo
,并将返回(0)代码>不会执行其中的任何代码,因为结果不会更改。如果注释代码sum+=1e-2,也会发生同样的情况代码>,编译器知道函数的唯一可能结果是返回(0)代码>,sum
被初始化为0,并且从不更改。这是一个GCC错误。Clang正确地优化您的代码以
foo: # @foo
xor eax, eax
ret
main: # @main
xor eax, eax
ret
在接近零的运行时间
printf被调用了多少次?为什么在foo()中使用double,因为它可以更快更准确地处理整数?@OldProgrammer在测试版本中从未调用过它,这就是为什么我对性能下降感到如此惊讶的原因。@LeeDanielCrocker我最小化了我原来的函数,忘记用MWE中的整数替换最终函数中需要的双精度。
foo: # @foo
xor eax, eax
ret
main: # @main
xor eax, eax
ret