C/C++高精度時間及其延時

1. 寫在前面

在分析算法的性能時,我們通過算法的時間複雜度可以從理論上分析出算法的大致高階,但是當我們想具體比較一下算法真正的性能時,往往希望在機器上測試並記錄其運行的真實時間,那麼就要用到C/C++中一些高精度時間函數。

2. 高精度時間結構體和函數

  1. 微秒
#include <sys/time.h>
struct timeval {
    time_t      tv_sec;     /* seconds */
    suseconds_t tv_usec;    /* microseconds */
};

獲取時間的函數:int gettimeofday(struct timeval *tv, struct timezone *tz);
demo:

  1. 納秒
#include <time.h>
struct timespec {
    time_t   tv_sec;        /* seconds */
    long     tv_nsec;       /* nanoseconds */
};
  1. chrono
    C++11推出的納秒級時間chrono.
auto start = std::chrono::system_clock::now();
auto end = std::chrono::system_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
// print timediff
std::cout << (double)(duration.count()) * std::chrono::microseconds::period::num / std::chrono::microseconds::period::den  << "s" << std::endl;

3. 高精度延時

若想簡單的話,可以用精度不太高的系統函數sleep()usleep()實現秒和微秒級定時,如果想高精度定時,查閱了大量博客發現,基本上都是用章節2中高精度時間來即使,即:

void timingus(size_t us)
{
    auto start = std::chrono::system_clock::now();
    while (1) 
    {
        auto end = std::chrono::system_clock::now();
        auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
        if (duration.count() > us) break;
    }
}

4. 測試代碼

#include <iostream>
#include <typeinfo>
#include <ctime>
#include <chrono>   
#include <sys/time.h>
#include <math.h>
#include <time.h>
#include <unistd.h>

void timingus(size_t us)
{
    auto start = std::chrono::system_clock::now();
    while (1) 
    {
        auto end = std::chrono::system_clock::now();
        auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
        if (duration.count() > us) break;
    }
}

void do_something(void) 
{
//     for (int i = 1000, a = 0; i >= 0; --i) {
//        for (int j = 1000; j >= 0; --j) {
//            for (int k = 100; k >= 0; --k) {
//                ++a;
//            }
//        }
//    }
    // usleep(1000);
    // sleep(1);
    timingus(1000000);

}
void func1(void) 
{
   clock_t start = clock();
   do_something();
   clock_t end = clock();
   std::cout << (double)(end - start) / CLOCKS_PER_SEC << std::endl;
}

void func2(void)
{
    auto start = std::chrono::system_clock::now();
    do_something();
    auto end = std::chrono::system_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
    std::cout << (double)(duration.count()) * std::chrono::microseconds::period::num / 
        std::chrono::microseconds::period::den  << "s" << std::endl;
}

void func3(void)
{
    struct timeval start, end;
    gettimeofday(&start, NULL);
    do_something();
    gettimeofday(&end, NULL);
    std::cout << (end.tv_sec + end.tv_usec / pow(10, 6)) - 
            (start.tv_sec + start.tv_usec / pow(10, 6)) << std::endl;
}

void func4(void)
{
    struct timespec start, end;
    clock_gettime(CLOCK_REALTIME, &start);
    do_something();
    clock_gettime(CLOCK_REALTIME, &end);
    std::cout << (end.tv_sec + end.tv_nsec / pow(10, 9)) - 
            (start.tv_sec + start.tv_nsec / pow(10, 9)) << std::endl;
}
int main()
{
    void (*p[])(void) = {func1, func2, func3, func4};

    for (size_t i = 0; i < sizeof(p) / sizeof(p[0]); ++i) 
    {
        p[i]();
    }
    
    return 0;
}

————————————————

5. 寫在後面

參考資料

  1. C++11 新的計時方法——std::chrono 大法好
  2. cppreference - chrono
  3. C++11 std::chrono庫詳解
  4. 【C/C++】時間精確到微秒、納秒
  5. c linux 獲取納秒時間
  6. C++11 中chrono庫 實現高精度定時
  7. c++11 chrono全面解析(最高可達納秒級別的精度)
  8. C++11 中chrono庫 實現高精度定時
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章