以毫秒精度测量时间

我的程序将在时间和空间上相互竞争不同的排序算法。 我有空间,但测量时间给我带来了一些麻烦。 以下是运行排序的代码:

void test(short* n, short len) { short i, j, a[1024]; for(i=0; i<2; i++) { // Loop over each sort algo memused = 0; // Initialize memory marker for(j=0; j<len; j++) // Copy scrambled list into fresh array a[j] = n[j]; // (Sorting algos are in-place) // ***Point A*** switch(i) { // Pick sorting algo case 0: selectionSort(a, len); case 1: quicksort(a, len); } // ***Point B*** spc[i][len] = memused; // Record how much mem was used } } 

(为简单起见,我删除了一些排序算法)

现在,我需要测量排序算法需要多长时间。 最明显的方法是在点(a)记录时间,然后从点(b)的时间减去该时间。 但是没有一个C时间函数足够好:

time()给了我几秒钟的时间,但algos比那更快,所以我需要更精确的东西。

自程序启动以来, clock()给我CPU滴答,但似乎舍入到最接近的10,000; 还不够小

time shell命令工作得很好,除了我需要为每个算法运行超过1,000个测试,我需要每个算法的单独时间。

我不知道getrusage()返回什么,但它也太长了。

我需要的是时间单位(显着,如果可能)小于排序function的运行时间:大约2ms。 所以我的问题是:我在哪里可以得到它?

gettimeofday()具有微秒分辨率并且易于使用。

一对有用的计时器function是:

 static struct timeval tm1; static inline void start() { gettimeofday(&tm1, NULL); } static inline void stop() { struct timeval tm2; gettimeofday(&tm2, NULL); unsigned long long t = 1000 * (tm2.tv_sec - tm1.tv_sec) + (tm2.tv_usec - tm1.tv_usec) / 1000; printf("%llu ms\n", t); } 

要测量时间,请使用带有CLOCK_MONOTONIC clock_gettime (如果可用,则使用CLOCK_MONOTONIC_RAW )。 尽可能避免使用gettimeofday 。 它特别推荐使用clock_gettime ,从中返回的时间可能会受到时间服务器的调整,这可能会导致您的测量结果失效。

您可以使用getrusage获取总用户+内核时间(或只选择一个),如下所示:

 #include  #include  double get_process_time() { struct rusage usage; if( 0 == getrusage(RUSAGE_SELF, &usage) ) { return (double)(usage.ru_utime.tv_sec + usage.ru_stime.tv_sec) + (double)(usage.ru_utime.tv_usec + usage.ru_stime.tv_usec) / 1.0e6; } return 0; } 

我选择创建一个包含小数秒的double精度数……

 double t_begin, t_end; t_begin = get_process_time(); // Do some operation... t_end = get_process_time(); printf( "Elapsed time: %.6f seconds\n", t_end - t_begin ); 

时间戳计数器在这里可能会有所帮助:

 static unsigned long long rdtsctime() { unsigned int eax, edx; unsigned long long val; __asm__ __volatile__("rdtsc":"=a"(eax), "=d"(edx)); val = edx; val = val << 32; val += eax; return val; } 

虽然有一些警告。 不同处理器核心的时间戳可以是不同的,并且改变时钟速度(由于省电特征等)可能导致错误的结果。