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

Pau*_*aul 2 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+=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;
}
Run Code Online (Sandbox Code Playgroud)

gcc -Ofast -std=c99 test.c -o test.exe使用gcc版本4.8.5进行编译。

为了找到一种优化我的功能的方法,我运行了time ./test.exe该程序,该程序指示我的计算机上的运行时间约为38秒。

当我删除线

        printf("warning message!\n");
        return(-1);
Run Code Online (Sandbox Code Playgroud)

或线

        sum+=1e-2; 
Run Code Online (Sandbox Code Playgroud)

运行时间减少到大约6s。

同样,当我将函数循环中的迭代次数更改为35时,速度也会提高,运行时间为6秒。将其增加到36可使运行时间为33s。

我在具有相同linux和gcc版本的另一台计算机上编译并运行了代码,并得到了相似的结果(随着计算机的老化,运行时间会稍长一些)。

是什么导致这种奇怪的行为?

小智 5

这不是一个奇怪的行为。如果删除这些行printfreturn(-1)然后该函数foo将由编译器优化,并且将return(0);不会执行该函数中的任何代码,因为结果不会更改。如果您对代码进行注释,也会发生相同的情况sum+=1e-2;,编译器会知道该函数的唯一可能结果是return(0);sum被初始化为0且永不更改。