我的程序将在时间和空间上相互竞争不同的排序算法。我有空间,但测量时间给我带来了一些麻烦。以下是运行各种类型的代码:
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()给了我几秒钟的时间,但算法比这快,所以我需要更准确的东西。
clock()给我自程序启动以来的CPU滴答,但似乎四舍五入到最近的10,000;还不够小
time shell命令运行得很好,除了我需要为每个算法运行超过1,000个测试,我需要每个算法的单独时间。
我不知道 getrusage()会返回什么,但它也太长了。
我需要的是时间单位(显着,如果可能)小于排序功能的运行时间:大约2ms。所以我的问题是:我在哪里可以得到它?
答案 0 :(得分:13)
gettimeofday()
具有微秒分辨率且易于使用。
一对有用的计时器功能是:
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);
}
答案 1 :(得分:9)
要测量时间,请将clock_gettime
与CLOCK_MONOTONIC
一起使用(如果可用,则使用CLOCK_MONOTONIC_RAW
)。尽可能避免使用gettimeofday
。它特别推荐使用clock_gettime
,并且从它返回的时间可能会受到时间服务器的调整,这可能会导致您的测量结果丢失。
答案 2 :(得分:3)
您可以使用getrusage
获取总用户+内核时间(或仅选择一个),如下所示:
#include <sys/time.h>
#include <sys/resource.h>
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 );
答案 3 :(得分:2)
时间戳计数器在这里可能会有所帮助:
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;
}
虽然有一些警告。不同处理器内核的时间戳可能不同,并且更改时钟速度(由于省电功能等)可能会导致错误的结果。