Linux下C++跨平台获取高精度时间戳

简介

C++语言本身及Linux操作系统均提供了时钟相关的函数,可以方便获取时间。

但是,在一些场合下,需要的时间精度不同,又不能通用。

如果依赖于Linux平台,又不能做到跨平台。

所以优化考虑使用C++语言本身提供的函数。

本文介绍使用 std::chrono 命名空间下的函数来获取时间戳。需要 c++11 支持。

关于时间函数的介绍,请参考 Linux c++获取本地毫秒级精确时间

获取时间跨度

在测试一段程序的耗时时,经常需要统计时间跨度。

示例代码如下:

int countTimeConsume()
{
    using namespace std::chrono;

    high_resolution_clock::time_point t1 = high_resolution_clock::now();

    std::cout << "printing out 1000 stars...\n";
    for (int i = 0; i < 1000; ++i)
        std::cout << "*";
    std::cout << std::endl;

    high_resolution_clock::time_point t2 = high_resolution_clock::now();

    duration<double, std::milli> time_span = t2 - t1; // 根据需要的精度调整参数

    std::cout << "It tooks me " << time_span.count() << " ms\n";

    return 0;
}

获取本地时间戳

有时,需要的是当时的时间戳,这样方便记录统计。

代码如下:

auto ts = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()).count(); // 根据需要调整时间精度,这里是us
// 返回类型为int64_t
一些测试

下面使用上述方法测试的示例:

#include <iostream>
#include <chrono>
#include <vector>

using namespace std;

int main(int argc, char *argv[])
{
    if (argc != 2) {
        cout << "Usage: " << argv[0] << " times" << endl;
        return -1;
    }

    int times = stoi(argv[1]);

    using namespace std::chrono;

    // cout
    high_resolution_clock::time_point t1 = high_resolution_clock::now();
    for (int i = 0; i < times; ++i) {
        cout << "guess how long can i took?\n";
    }
    high_resolution_clock::time_point t2 = high_resolution_clock::now();
    duration<double, std::micro> time_span = t2 - t1; // 根据需要的精度调整参数
    std::cout << "cout 1 msg tooks " << time_span.count() / times << " us\n";

	// nothing, but system call
    double sum = 0;
    for (int i = 0; i < times; ++i) {
        t1 = high_resolution_clock::now();
        t2 = high_resolution_clock::now();
        time_span = t2 - t1;
        sum += time_span.count();
    }
    std::cout << "do nothing tooks " << sum / times << " us\n";
    
    // local var
    t1 = high_resolution_clock::now();
    for (int i = 0; i < times; ++i) {
        int local_var = 0;
    }
    t2 = high_resolution_clock::now();
    time_span = t2 - t1;
    std::cout << "set a local var tooks " << time_span.count() / times << " us\n";

    // vector
    t1 = high_resolution_clock::now();
    int elements = 5000;
    for (int i = 0; i < times; ++i) {
        vector<int> vi;
        vi.reserve(elements);
        for (int j = 0; j < elements; ++j) {
            vi.emplace_back(j);
        }
    }
    t2 = high_resolution_clock::now();
    time_span = t2 - t1;
    std::cout << "vector emplace_back " << elements << " elements tooks " << time_span.count() / times << " us\n";

    return 0;
}

运行结果如下:

% ./a.out 1|grep -v guess 
cout 1 msg tooks 25.436 us
do nothing tooks 0.083 us
set a local var tooks 0.086 us
vector emplace_back 5000 elements tooks 182.384 us

% ./a.out 10|grep -v guess 
cout 1 msg tooks 1.9276 us
do nothing tooks 0.0471 us
set a local var tooks 0.012 us
vector emplace_back 5000 elements tooks 166.131 us

% ./a.out 100|grep -v guess 
cout 1 msg tooks 0.26123 us
do nothing tooks 0.04654 us
set a local var tooks 0.00515 us
vector emplace_back 5000 elements tooks 164.591 us

% ./a.out 1000|grep -v guess 
cout 1 msg tooks 0.115601 us
do nothing tooks 0.045135 us
set a local var tooks 0.004459 us
vector emplace_back 5000 elements tooks 163.989 us

% ./a.out 10000|grep -v guess 
cout 1 msg tooks 0.0959567 us
do nothing tooks 0.0451172 us
set a local var tooks 0.004393 us
vector emplace_back 5000 elements tooks 115.837 us

% ./a.out 100000|grep -v guess
cout 1 msg tooks 0.101854 us
do nothing tooks 0.0457887 us
set a local var tooks 0.00438674 us
vector emplace_back 5000 elements tooks 93.8223 us

测试服务器性能如下:

% lscpu
Architecture:        x86_64
CPU op-mode(s):      32-bit, 64-bit
Byte Order:          Little Endian
CPU(s):              16
On-line CPU(s) list: 0-15
Thread(s) per core:  2
Core(s) per socket:  4
Socket(s):           2
NUMA node(s):        2
Vendor ID:           GenuineIntel
CPU family:          6
Model:               44
Model name:          Intel(R) Xeon(R) CPU           E5640  @ 2.67GHz
Stepping:            2
CPU MHz:             2925.607
BogoMIPS:            5320.01
Virtualization:      VT-x
L1d cache:           32K
L1i cache:           32K
L2 cache:            256K
L3 cache:            12288K
NUMA node0 CPU(s):   0,2,4,6,8,10,12,14
NUMA node1 CPU(s):   1,3,5,7,9,11,13,15
Flags:               fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid dca sse4_1 sse4_2 popcnt aes lahf_lm pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid dtherm ida arat flush_l1d
小结

时间统计在对程序进行性能分析和优化时经常使用,可以封装到公用类中使用。

注意,由于Linux系统不是实时操作系统,当时间精度特别小时,可能会有一定误差。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值