浅析Linux中的时间编程和实现原理(一) Linux应用层的时间编程
时间的测量 有时候我们要计算某段程序执行的时间,比如需要对算法进行时间分析。基本的实现思路为在被测试代码的开始和结束的地方获取当时时间,相减后得到相对值,即所需要的统计时间。为了实现高精度的时间测量,必须使用高精度的时间获取方式,一般有两种方法: 系统调用 gettimeofday 汇编指令 RDTSC。 gettimeofday 可以使用 gettimeofday() 函数进行时间测量,其精度在 us 级别,可以用来做一般的时间分析。 gettimeofday() 将时间保存在结构 tv 之中。gettimeofday() 的第二个参数代表时区,在 Linux 中已经废弃不用,只能用 NULL 传入。一个典型的例子程序如下: 清单 6,gettimeofday 例子程序 void function() { unsigned int i,j; double y; for(i=0;i<1000;i++) for(j=0;j<1000;j++) y=sin((double)i); //耗时操作 } main() { struct timeval tpstart,tpend; float timeuse; gettimeofday(&tpstart,NULL); //记录开始时间戳 function(); gettimeofday(&tpend,NULL); //记录结束时间戳 timeuse = 1000000*(tpend.tv_sec-tpstart.tv_sec)+ tpend.tv_usec-tpstart.tv_usec; //计算差值 timeuse /= 1000000; printf("Used Time:%fn",timeuse); exit(0); } 这个程序输出函数的执行时间,我们可以使用这个来进行系统性能的测试,或者是函数算法的效率分析。在我个人机器上的输出结果是:Used Time:0.556070 RDTSC gettimeofday() 是一个系统调用,在某些场合下频繁调用它是不合适的。比如性能要求很高的代码段内。因为 gettimeofday() 需要用户态/内核态切换,开销较大。Intel X86 处理器提供了 TSC 硬件,并且可以用非特权指令 rdtsc 来读取该硬件的时间值,这就避免了过度的内核用户态切换。 如何使用 RDTSC 参考下面的例子代码,采用 GCC 的汇编扩展,定义 rdtsc 的函数,它返回当前时间戳。 #define rdtsc(low,high) __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high)) 在 C 代码中使用 rdtsc 十分简单。比如: 清单 7,RDTSC 例子程序 unsigned long long get_cycles() { unsigned low, high; unsigned long long val; rdtsc(low,high); val = high; val = (val << 32) | low; //将 low 和 high 合成一个 64 位值 return val; } double get_cpu_mhz(void) { FILE* f; char buf[256]; double mhz = 0.0; f = fopen("/proc/cpuinfo","r"); //打开 proc/cpuinfo 文件 if (!f) return 0.0; while(fgets(buf, sizeof(buf), f)) { double m; int rc; rc = sscanf(buf, "cpu MHz : %lf", &m); //读取 cpu MHz if (mhz == 0.0) { mhz = m; break; } } fclose(f); return mhz; //返回 HZ 值 } int main() { double mhz; mhz = get_cpu_mhz(); cycles_t c1, c2; for(;;) { c1 = get_cycles(); sleep(1); c2 = get_cycles(); //c2 和 c1 的差值应该为 1000000us,即 1 秒 printf("1 sec = %g usecn", (c2 - c1) / mhz); } } 函数 get_cycles 将返回 64 位整数,代表当前时间,单位是 CPU 的 cycle 数。函数 get_cpu_mhz 获得当前 CPU 的工作频率。用两个 CPU cycle 的差值除以 CPU 频率,就是微妙。 但 RDTSC 只能在 IA 系列处理器上使用。而且由于处理器的乱序执行,RDTSC 有些情况下并不准确,在 SMP 下使用 RDTSC 也有一定的问题。但这些问题只有在需要极高时间精度的情况下才会出现,对于一般的时间测量要求,采用 RDTSC 是一个可以考虑的选择。 (编辑:应用网_丽江站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |