C 函数运行时的非线性行为

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

我有一个计算总和的函数,根据总和的结果执行特定任务或发出警告消息。我需要在粒子轨迹模拟中运行此函数数百万次(它计算与时间和位置相关的力),并注意到我的代码非常慢

这是我的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;
}
还是排队

        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