簡體   English   中英

以毫秒精度測量時間

[英]Measuring time in millisecond precision

我的程序將在時間和空間上相互競爭不同的排序算法。 我有空間,但測量時間給我帶來了一些麻煩。 以下是運行排序的代碼:

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()返回什么,但它也太長了。

我需要的是時間單位(顯着,如果可能)小於排序功能的運行時間:大約2ms。 所以我的問題是:我在哪里可以得到它?

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);
}

要測量時間, CLOCK_MONOTONIC clock_gettimeCLOCK_MONOTONIC一起CLOCK_MONOTONIC (如果可用,則使用CLOCK_MONOTONIC_RAW )。 盡可能避免使用gettimeofday 它特別推薦使用clock_gettime ,並且從它返回的時間可能會受到時間服務器的調整,這可能會導致您的測量結果失效。

您可以使用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 );

時間戳計數器在這里可能會有所幫助:

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;
}

雖然有一些警告。 不同處理器核心的時間戳可以是不同的,並且改變時鍾速度(由於省電特征等)可能導致錯誤的結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM