前置
C++ 标准:C++11
头文件:<chrono>
简介
namespace std::chrono
中提供了三(两)种可用的时钟:std::chrono::_V2::steady_clock
、std::chrono::_V2::system_clock
、std::chrono::_V2::high_resolution_clock
。
这之中,steady_clock
提供精度较高的稳定时钟,system_clock
提供精度更高但随系统时间变化的时钟。high_resolution_clock
“表示实现提供的拥有最小计次周期的时钟;它可以是 system_clock
或 steady_clock
的别名,或第三个独立时钟。”(来源,有调整)
具体地,在 Intel(R) Core(TM) i5-9500T CPU @ 2.20GHz 的 CPU 环境下使用 Windows 10 Pro 21H2 操作系统的 g++ 11.2.0 编译出的 steady_clock
具有 100 ns
的精度,system_clock
具有 1 ns
的精度。[1]
本文主要讨论如何使用 steady_clock
实现计时。
[1] g++ -v
的输出:
1 2 3 4 5 6 7 8
| Using built-in specs. COLLECT_GCC=E:\qidirj\RedPanda-Cpp\MinGW64\bin\g++.exe COLLECT_LTO_WRAPPER=E:/qidirj/RedPanda-Cpp/MinGW64/bin/../libexec/gcc/x86_64-w64-mingw32/11.2.0/lto-wrapper.exe Target: x86_64-w64-mingw32 Configured with: ../../../src/gcc-11.2.0/configure --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --prefix=/mingw64 --with-sysroot=/d/a/mingw-builds/mingw-builds/buildroot/x86_64-1120-posix-seh-rt_v9-rev1/mingw64 --enable-host-shared --disable-multilib --enable-languages=c,c++,lto --enable-libstdcxx-time=yes --enable-threads=posix --enable-libgomp --enable-libatomic --enable-lto --enable-graphite --enable-checking=release --enable-fully-dynamic-string --enable-version-specific-runtime-libs --enable-libstdcxx-filesystem-ts=yes --disable-libstdcxx-pch --disable-libstdcxx-debug --enable-bootstrap --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-gnu-as --with-gnu-ld --with-arch=nocona --with-tune=core2 --with-libiconv --with-system-zlib --with-gmp=/d/a/mingw-builds/mingw-builds/buildroot/prerequisites/x86_64-w64-mingw32-static --with-mpfr=/d/a/mingw-builds/mingw-builds/buildroot/prerequisites/x86_64-w64-mingw32-static --with-mpc=/d/a/mingw-builds/mingw-builds/buildroot/prerequisites/x86_64-w64-mingw32-static --with-isl=/d/a/mingw-builds/mingw-builds/buildroot/prerequisites/x86_64-w64-mingw32-static --with-pkgversion='x86_64-posix-seh-rev1, Built by MinGW-W64 project' --with-bugurl=https://sourceforge.net/projects/mingw-w64 CFLAGS='-O2 -pipe -fno-ident -I/d/a/mingw-builds/mingw-builds/buildroot/x86_64-1120-posix-seh-rt_v9-rev1/mingw64/opt/include -I/d/a/mingw-builds/mingw-builds/buildroot/prerequisites/x86_64-zlib-static/include -I/d/a/mingw-builds/mingw-builds/buildroot/prerequisites/x86_64-w64-mingw32-static/include' CXXFLAGS='-O2 -pipe -fno-ident -I/d/a/mingw-builds/mingw-builds/buildroot/x86_64-1120-posix-seh-rt_v9-rev1/mingw64/opt/include -I/d/a/mingw-builds/mingw-builds/buildroot/prerequisites/x86_64-zlib-static/include -I/d/a/mingw-builds/mingw-builds/buildroot/prerequisites/x86_64-w64-mingw32-static/include' CPPFLAGS=' -I/d/a/mingw-builds/mingw-builds/buildroot/x86_64-1120-posix-seh-rt_v9-rev1/mingw64/opt/include -I/d/a/mingw-builds/mingw-builds/buildroot/prerequisites/x86_64-zlib-static/include -I/d/a/mingw-builds/mingw-builds/buildroot/prerequisites/x86_64-w64-mingw32-static/include' LDFLAGS='-pipe -fno-ident -L/d/a/mingw-builds/mingw-builds/buildroot/x86_64-1120-posix-seh-rt_v9-rev1/mingw64/opt/lib -L/d/a/mingw-builds/mingw-builds/buildroot/prerequisites/x86_64-zlib-static/lib -L/d/a/mingw-builds/mingw-builds/buildroot/prerequisites/x86_64-w64-mingw32-static/lib ' LD_FOR_TARGET=/d/a/mingw-builds/mingw-builds/buildroot/x86_64-1120-posix-seh-rt_v9-rev1/mingw64/bin/ld.exe --with-boot-ldflags=' -Wl,--disable-dynamicbase -static-libstdc++ -static-libgcc' Thread model: posix Supported LTO compression algorithms: zlib gcc version 11.2.0 (x86_64-posix-seh-rev1, Built by MinGW-W64 project)
|
原型
std::chrono::steady_clock
1 2 3 4 5 6 7 8 9 10 11 12
| struct steady_clock { typedef chrono::nanoseconds duration; typedef duration::rep rep; typedef duration::period period; typedef chrono::time_point<steady_clock, duration> time_point;
static constexpr bool is_steady = true;
static time_point now() noexcept; };
|
std::chrono::time_point_cast
1 2 3 4 5 6 7 8
| template<typename _ToDur, typename _Clock, typename _Dur> constexpr typename enable_if<__is_duration<_ToDur>::value, time_point<_Clock, _ToDur>>::type time_point_cast(const time_point<_Clock, _Dur>& __t) { typedef time_point<_Clock, _ToDur> __time_point; return __time_point(duration_cast<_ToDur>(__t.time_since_epoch())); }
|
std::chrono::_V2::steady_clock::time_point::time_since_epoch()
1 2 3
| constexpr duration time_since_epoch() const { return __d; }
|
用法
获取当前相对时间
1
| chrono::time_point_cast<chrono::nanoseconds>(chrono::steady_clock::now()).time_since_epoch()
|
chrono::steady_clock::now()
获取相对于一定时间点的当前时间,这个时间点可能是系统启动的时间、UNIX 时间起点等等。
接着,利用 chrono::time_point_cast<chrono::nanoseconds>()
将这个时间转换为纳秒形式,用 time_since_epoch
获取到相对时间。
求时间差
以上的表达式返回 std::chrono::_V2::steady_clock::duration
类型,其有 count()
成员函数,返回时间的整型形式,一般为 long long
类型。这之后,可以利用两个 duration
的 count
之差算出时间差,注意单位为纳秒。
实现计时
保存一个 std::chrono::_V2::steady_clock::duration start
,在开始时将当前时间传入 start
,则在任何时刻可以作差取到时间。