为什么在同一台计算机上相同代码的执行时间可能会不同?

时间:2019-01-19 21:58:13

标签: c

我是C编程的新手,我编写了代码,并希望获得其运行时。这是我所做的。每次我运行代码时,我都会得到一个不同的运行时值。这样对吗?还是我的代码有问题?

int main(int argc, char *argv[])
{
    time_t start,end;
    start=clock();
    // this part is some operation

    end=clock();
    int running_time=end-start;
    printf("Time taken: %d",running_time);
    return 0;
}

3 个答案:

答案 0 :(得分:4)

代码没有问题。 它对您的程序执行的OS调度程序的了解,一直都在变化。

答案 1 :(得分:1)

这取决于您观察到的变化。在现代计算机中,所有这些功能都可以从统计角度优化平均运行时间。但是,许多体系结构功能都是基于统计信息的,并且取决于初始条件可能导致非常不同的运行时间。这主要包括缓存和分支预测器。在运行时偏差通常在20%到30%之间。而且我们在无金属裸机无操作系统系统上进行了实验,并且行为表现相同。

这是一个使用时间戳计数器测量时间(周期)的程序。可以测试两个简单的功能。一个只是向量的零,第二个是对随机(但始终相同)向量的一组测试。

#include <stdio.h>
#include <stdlib.h>
#define N 1000000
#define TYPE int
#define ZERO 0

static unsigned long long start_timer() ;
static unsigned long long stop_timer() ;
static double dtime(long long debut, long long fin);


#ifdef __i386__
#  define RDTSC_DIRTY "%eax", "%ebx", "%ecx", "%edx"
#elif __x86_64__
#  define RDTSC_DIRTY "%rax", "%rbx", "%rcx", "%rdx"
#else
# error unknown platform
#endif


static inline unsigned long long start_timer() 
{ 
  unsigned int hi = 0, lo = 0; 

  asm volatile("cpuid\n\t"
           "rdtscp\n\t"
           "mov %%edx, %0\n\t"
           "mov %%eax, %1\n\t" 
           : "=r" (hi), "=r" (lo)
           :: RDTSC_DIRTY);      
  unsigned long long that =   (unsigned long long)((lo) |
                           (unsigned long long)(hi)<<32);

  return that; 
} 

static inline unsigned long long stop_timer() 
{ 
  unsigned int hi = 0, lo = 0; 

  asm volatile("rdtscp\n\t"    
           "mov %%edx, %0\n\t" 
           "mov %%eax, %1\n\t" 
           "cpuid\n\t"     
           : "=r" (hi), "=r" (lo)
           :: RDTSC_DIRTY);      
  unsigned long long that =   (unsigned long long)((lo) |
                           (unsigned long long)(hi)<<32);

  return that; 
} 

static inline double dtime(long long start, long long end)
{
  return (double) (end - start) ;
}


TYPE BF[N] ;

long long start, end;
double benchtime;


void zero(){
  int i, j, m ;
  start=start_timer();
  for (i=0;i<N;i++)
    BF[i]=ZERO;
  benchtime=dtime(start, stop_timer());

  printf ("%g\n", benchtime);
}

void randtest(){
  int i, j, m ;
  srandom(100);
  for (i=0;i<N;i++)
    BF[i]=random();
  int count=0;
  start=start_timer();
  for (i=0;i<N;i++){
    if (BF[i]>RAND_MAX/2)
      count++;
  }
  benchtime=dtime(start, stop_timer());

  printf ("%g\n", benchtime);
}



void main()
{
  #ifdef ZEROTEST
  zero();
  #else
  randtest();
  #endif
} 

以下是结果:

  

am @ Mandel:〜/ tmp / d $ cc -DZEROTEST time.c;对于i in 1 2 3 4 5 6 7 8 9 10;做./a.out;完成

     

1.09084e + 07 1.14298e + 07 1.07197e + 07 1.26519e + 07 1.32742e + 07 1.37184e + 07 1.54689e + 07 1.36335e + 07 1.20818e + 07 1.12298e + 07

     

am @ Mandel:〜/ tmp / d $ cc -DZEROTEST -O time.c;对于i in 1 2 3 4 5 6 7 8 9 10;做./a.out;完成

     

4.30112e + 06 4.37242e + 06 4.28102e + 06 4.51831e + 06 4.45952e + 06 5.77813e + 06 6.33686e + 06 5.44415e + 06 5.67434e + 06 5.90118e + 06

     

am @ Mandel:〜/ tmp / d $ cc time.c;对于i in 1 2 3 4 5 6 7 8 9 10;做./a.out;完成

     

2.4763e + 07 2.77489e + 07 2.78568e + 07 3.3762e + 07 3.56298e + 07 3.66709e + 07 3.22833e + 07 2.68651e + 07 2.88412e + 07 2.92287e + 07

     

am @ Mandel:〜/ tmp / d $ cc -O time.c;对于i in 1 2 3 4 5 6 7 8 9 10;做./a.out;完成

     

1.00543e + 06 1.15819e + 06 1.00544e + 06 2.74409e + 06 1.17561e + 06 1.40751e + 06 2.41898e + 06 1.65623e + 06 2.19502e + 06 1.59414e + 06

如您所见,通常至少会有30%的时间变化,但是当涉及到分支预测变量时,时间变化可能更大。它发生在优化或未优化的代码中。

您不能认为执行在现代体系结构中是确定性的。由于架构设计的选择,其变化至少与OS效果同样重要。当涉及到实时性时,这是一个主要困难。

答案 2 :(得分:0)

运行时间变化是很正常的,因为您的计算机可能正在运行很多东西(包括您的OS),不仅是那段代码,而且还会影响时钟速度。

在处理消耗非常稳定的计算机上,运行时间应该应该保持

您的代码没有错。