|
在linux下通常可用的精度最高的时间接口是gettimeofday,它返回一个timeval结构,其精度为us,即10-6 秒,大多数情况这个精度已经够用了。不过有时为了更高的精度,比如纳秒级的时间精度,我们需求探索Linux为我们提供的时间调用。
测试占用的时钟周期,结果如下:
rdtsc, 22 cycles
rdtsc_serial, 294 cycles
clock, 437 cycles
gettimeofday, 53 cycles
可见,Linux下 gettimeofday 是一个折中选择
(代码来自上篇的链接)
[cpp] view plaincopy
#if defined(_MSC_VER)
#undef inline
#define inline __forceinline
#pragma comment( lib, "Winmm.lib" )
#include <windows.h>
#else
#include <sys/time.h>
#endif
#include <math.h>
#include <stdio.h>
#include <time.h>
#include "Profiler.h"
struct rdtsc { inline void getTicks() { Profiler::Timer::getticks(); } };
struct rdtsc_serial { inline void getTicks() { Profiler::Timer::getticks_serial(); } };
struct clck { inline void getTicks() { clock(); } };
#if defined(_MSC_VER)
struct qpc { inline void getTicks() { LARGE_INTEGER li; QueryPerformanceCounter( &li ); } };
struct tgt { inline void getTicks() { timeGetTime(); } };
#else
struct gtod { inline void getTicks() { timeval t; gettimeofday( &t, NULL); } };
#endif
template< class Timer > double time( const int trials ) {
Timer t;
Profiler::u64 min = 1000000000000000ULL;
for ( int run = 0; run < 5000; run++ ) {
Profiler::Timer measure;
{
ScopedTimer scoped( measure );
for ( int i = 0; i < trials; i++ )
t.getTicks();
}
if ( measure.ticks < min )
min = measure.ticks;
}
return Profiler::average( min, trials );
}
int main( int argc, const char *argv[] ) {
const int trials = 1000;
printf( "rdtsc, %.0f cycles\n", time<rdtsc>( trials ) );
printf( "rdtsc_serial, %.0f cycles\n", time<rdtsc_serial>( trials ) );
printf( "clock, %.0f cycles\n", time<clck>( trials ) );
#if defined(_MSC_VER)
printf( "QueryPerformanceCounter, %.0f cycles\n", time<qpc>( trials ) );
printf( "timeGetTime, %.0f cycles\n", time<tgt>( trials ) );
#else
printf( "gettimeofday, %.0f cycles\n", time<gtod>( trials ) );
#endif
return 0;
}
|
|