Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C getrusage返回四舍五入的数字_C_Linux - Fatal编程技术网

C getrusage返回四舍五入的数字

C getrusage返回四舍五入的数字,c,linux,C,Linux,我试图使用rusage测量各种函数调用的资源使用时间(用户和系统)。 我发现我得到的结果大约是10毫秒,比如0秒70000us、10000 US等。请告诉我是否有办法设置getrusage的精度/粒度 我的程序很简单: #include<stdio.h> #include<string.h> #include<stdlib.h> #include <sys/time.h> #include <sys/resource.h> #inclu

我试图使用rusage测量各种函数调用的资源使用时间(用户和系统)。 我发现我得到的结果大约是10毫秒,比如0秒70000us、10000 US等。请告诉我是否有办法设置getrusage的精度/粒度

我的程序很简单:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>

int main(){
  struct rusage usage;
  struct timeval start, end;
  int i, j, k = 0;

  getrusage(RUSAGE_SELF, &usage);
  start = usage.ru_utime;
  printf("buffer check\n");
  char *str = "---";
  int arr[100],ctr;

  for(ctr = 0;ctr<100;ctr++){

    arr[ctr] = ctr + 1000;

  }

  for (i = 0; i < 10000; i++) {
     for (j = 0; j < 10000; j++) {
      k += 20;
  }
 }

 getrusage(RUSAGE_SELF, &usage);
 end = usage.ru_utime;

 printf("Started at: %ld.%lds\n", start.tv_sec, start.tv_usec);
 printf("Ended at: %ld.%lds\n", end.tv_sec, end.tv_usec);

 return 1;
}
#包括
#包括
#包括
#包括
#包括
#包括
int main(){
结构图像使用;
结构timeval开始、结束;
int i,j,k=0;
getrusage(RUSAGE_SELF和usage);
开始=usage.ru_utime;
printf(“缓冲区检查”);
char*str=“--”;
int arr[100],中心线;

对于(ctr=0;ctr许多操作系统不能精确计算进程使用的时间。在许多情况下,读取每个上下文开关和系统调用上的时钟代价太高,在其他情况下,硬件甚至可能没有允许您精确计时的时钟

getrusage
获得的一种非常常用的计算方法是使用一个100Hz(通常是100Hz,虽然64Hz和1024Hz也很常见)的计时器中断,对中断时系统上发生的情况进行采样。因此,内核每秒检查100次当前正在运行的内容和位置(用户空间用于ru_utime或内核空间用于ru_stime)并递增一个计数器。然后,该计数器被解释为您的程序运行10毫秒

你可以在你的系统上用
clock\u gettime
进行实验,看看它是否有每进程计数器,有时这些计数器可能比
getrusage
计数器更精确。但我不会抱太大希望,如果10ms的分辨率是
getrusage
所能做到的最好分辨率,那么
clock\u gettime
很可能没有更好的分辨率离子或任何进程时钟

如果操作系统中的时钟对您的测量来说不够好,您唯一的选择就是重复测试运行几分钟,然后将得到的结果除以运行次数

事实上,
gettimeofday
更精确并不意味着什么。
gettimeofday
可能相对昂贵。想想内核需要做哪些工作才能准确地跟踪进程的用户和系统时间。每次进行系统调用时,都需要两次时间戳(一个用于系统调用的开始,一个用于结束)只是为了跟踪您使用了多少系统时间。为了跟踪用户时间,您需要在每次系统切换到另一个进程时设置时间戳。许多系统确实会跟踪第二个进程,但不会跟踪第一个进程,因为系统调用比进程上下文切换更常见(这就是为什么我建议检查
clock\u gettime
,因为它可以有一个计时器来累积进程的总系统时间和用户时间)

现代系统中的时钟非常烦人,因为尽管获取时间戳是最常见的系统调用之一,但我们仍然经常需要通过缓慢的总线进行拖网,并进行重锁以获取时钟。已经使用了其他解决方案,如cpu上的周期计数器,但这些解决方案非常不准确,因为它们可能与即使是CPU,可能有一个可变的频率,可以停止在操作系统的控制之外,等等。你需要知道你的CPU的确切型号,以便能够可靠地使用它们。操作系统有很多启发式方法来确定使用哪种时钟,但这可能意味着两台alm机器之间存在巨大的差异ost同样如此。一个可能会得到一个亚纳秒精度的周期计数器,读取一条指令需要花费一个指令,而另一条指令需要通过ISA总线到一个30年的芯片设计,具有微秒精度或更差的精度,需要数千个周期才能读取。

我的新程序:
My new program:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
//int clock_gettime(clockid_t clk_id, struct timespect *tp);

#define BILLION  1000000000L;

void testClockGetTime(clockid_t clk_id , struct timespec *start , struct timespec  *stop){

   long temp = 0,i;
   unsigned long accumsec,accumns;
   if( clock_gettime( clk_id, start) == -1 ) {
      perror( "clock gettime" );
      exit( EXIT_FAILURE );
   }
   for ( i = 0; i< 24222000; i++)
       temp+=temp;

   if( clock_gettime( clk_id, stop) == -1 ) {
      perror( "clock gettime" );
      exit( EXIT_FAILURE );
    }
    accumsec = stop->tv_sec - start->tv_sec;
    accumns =  stop->tv_nsec - start->tv_nsec;
    if(stop->tv_nsec<start->tv_nsec){
       accumsec = accumsec - 1;
       accumns = start->tv_nsec - stop->tv_nsec;
    }

    printf( " sec %ld\n", accumsec );
    printf(" ns %ld\n", accumns );

  }

int main( int argc, char **argv )
 {
   struct timespec start, stop;
   struct timeval tds,tdse;
   memset(&tds,0,sizeof(struct timeval));
   memset(&tdse,0,sizeof(struct timeval));
   unsigned long accumsec,accumns;
   long timesec, timeusec;
   printf("checking on various timers gives by clockGetTime \n");
   printf("cpu time\n");
   memset(&stop,0,sizeof(struct timespec));
   memset(&start,0,sizeof(struct timespec));
   testClockGetTime(CLOCK_PROCESS_CPUTIME_ID , &start,&stop);
   memset(&start,0,sizeof(struct timespec));
   memset(&stop,0,sizeof(struct timespec));
   printf("real time\n");    
   testClockGetTime(CLOCK_REALTIME,&start,&stop);
   memset(&start,0,sizeof(struct timespec));
   memset(&stop,0,sizeof(struct timespec));
   printf("monotonic\n");    
   testClockGetTime(CLOCK_MONOTONIC,&start,&stop);
   memset(&start,0,sizeof(struct timespec));
   memset(&stop,0,sizeof(struct timespec));
   printf("thread\n");
   testClockGetTime(CLOCK_THREAD_CPUTIME_ID,&start,&stop);
   memset(&start,0,sizeof(struct timespec));
   memset(&stop,0,sizeof(struct timespec));
   gettimeofday(&tds, NULL);
   long temp,i;
   for ( i = 0; i< 24222000; i++)
      temp+=temp;
   gettimeofday(&tdse, NULL);
   if( clock_gettime( CLOCK_PROCESS_CPUTIME_ID, &stop) == -1 ) {
      perror( "clock gettime" );
      exit( EXIT_FAILURE );
    }

    //   accumsec = stop.tv_sec - start.tv_sec; 
    //   accumns =  stop.tv_nsec - start.tv_nsec; 
    //   if(stop.tv_nsec<start.tv_nsec){
    //     accumsec = accumsec - 1;
    //     accumns = start.tv_nsec - stop.tv_nsec;
    //   }

    //   printf( "proc sec %ld\n", accumsec );
    //   printf( "proc ns %ld\n", accumns );
    //    printf("before day =%ld,%ld\n",tds.tv_sec,tds.tv_usec);
    //    printf("after day=%ld,%ld\n",tdse.tv_sec, tdse.tv_usec);
    timesec =  tdse.tv_sec - tds.tv_sec;
    timeusec=  tdse.tv_usec- tds.tv_usec;
  if(tdse.tv_usec < tds.tv_usec){
    timesec = timesec - 1;
    timeusec= tds.tv_usec - tdse.tv_usec;
   }
   printf("daytime sec =%ld\n",timesec);
   printf("daytime usec=%ld\n",timeusec);
   return( EXIT_SUCCESS );
 }
#包括 #包括 #包括 #包括 //int clock_gettime(clockid_t clk_id,struct timespect*tp); #定义10亿1000000000L; void testClockGetTime(clockid\u t clk\u id,struct timespec*start,struct timespec*stop){ 长期温度=0,i; 无符号长累加器,累加器; 如果(时钟获取时间(时钟id,开始)=-1){ perror(“时钟获取时间”); 退出(退出失败); } 对于(i=0;i<24222000;i++) 温度+=温度; 如果(时钟获取时间(时钟id,停止)=-1){ perror(“时钟获取时间”); 退出(退出失败); } accumsec=停止->电视秒-启动->电视秒; accumns=停止->tv\u nsec-启动->tv\u nsec; 如果(停止->电视节目电视节目){ accumsec=accumsec-1; accumns=开始->电视节目-停止->电视节目; } printf(“秒%ld\n”,累计); printf(“ns%ld\n”,累计); } int main(int argc,字符**argv) { 结构timespec启动、停止; 结构timeval-tds,tdse; memset(&tds,0,sizeof(struct timeval)); memset(&tdse,0,sizeof(struct timeval)); 无符号长累加器,累加器; 长timesec,timeusec; printf(“通过clockGetTime检查各种计时器\n”); printf(“cpu时间”); memset(&stop,0,sizeof(struct timespec)); memset(&start,0,sizeof(struct timespec)); testClockGetTime(时钟、进程、CPU时间、ID、启动和停止); memset(&start,0,sizeof(struct timespec)); memset(&stop,0,sizeof(struct timespec)); printf(“实时\n”); testClockGetTime(时钟实时、启动和停止); memset(&start,0,sizeof(struct timespec)); memset(&stop,0,sizeof(struct timespec)); printf(“单调的”; testClockGetTime(时钟单调、开始和停止); memset(&start,0,sizeof(struct timespec)); memset(&stop,0,sizeof(struct timespec)); printf(“线程\n”); testClockGetTime(时钟线程CPUTIME ID、启动和停止); memset(&start,0,sizeof(struct timespec)); memset(&stop,0,sizeof(struct timespec)); gettimeofday(&tds,NULL); 长时间,我; 对于(i=0;i<24222000;i++) 温度+=温度; gettimeofday(&tdse,NULL); if(时钟获取时间(时钟处理时间ID和停止)=-1){ perror(“时钟获取时间