讲师中心 微信公众号

工具推荐

视频效率加速
AniShort
AniShort

AI短剧协同制作平台

立刻MV
立刻MV

低成本歌曲 MV、视频生成

updream

一键生成高质量推广成片

Laper
Laper

剧本策划到成片协作

C++如何实现支持跨平台的高精度单调时钟类?(性能基准测试基础)

酷晨小哥_1875

酷晨小哥_1875

发布时间:2026-02-28 15:59:22

|

431人浏览过

|

来源于php中文网

原创

应优先使用 std::chrono::steady_clock 测量性能,因其跨平台、单调、不随系统时间跳变;避免误用 system_clock 或 high_resolution_clock,并防止编译器优化待测代码。

c++如何实现支持跨平台的高精度单调时钟类?(性能基准测试基础)

用 std::chrono::steady_clock 就够了,别自己封装

标准库的 std::chrono::steady_clock 就是为此而生的:跨平台、单调、不随系统时间调整跳变、精度足够做性能基准。Windows 上它底层调用 QueryPerformanceCounter,Linux/macOS 通常映射到 CLOCK_MONOTONIC,所有主流编译器都支持。自己用 gettimeofday、clock_gettime 或 WinAPI 手写反而容易出兼容性问题。

常见错误现象:std::chrono::system_clock 被误用——它可能因 NTP 校时或手动改系统时间而倒退或跳跃,导致基准测试结果负值或剧烈抖动;std::chrono::high_resolution_clock 在部分旧版 libstdc++(如 GCC 4.8)中只是 system_clock 的别名,不保证单调。

  • 始终优先用 std::chrono::steady_clock,不是“高精度”就一定更好
  • 避免依赖 high_resolution_clock,它的语义在 C++11/14 中未严格规定
  • 构造时不要用 time_since_epoch() 直接转整数——不同平台 epoch 基准不同,只用于相对差值

如何安全地测一段代码的耗时(纳秒级)

核心是避免编译器优化掉待测逻辑,同时防止时钟调用本身引入显著偏差。直接用 steady_clock::now() 两次取差是最轻量、最可靠的方式。

使用场景:微基准(microbenchmark),比如比较两个 memcpy 实现、测量 hash 函数单次开销。

立即学习“C++免费学习笔记(深入)”;

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载
  • 必须把待测代码放在 volatile 变量读写之间,或用 asm volatile("" ::: "memory") 内存栅栏(GCC/Clang),否则编译器可能整个优化掉
  • 不要用 auto start = steady_clock::now() 然后 duration_cast<nanoseconds>(end - start).count()</nanoseconds> —— count() 返回的是 rep 类型(可能是 long long 或 int64_t),直接打印或参与计算前先确认是否溢出
  • 单次测量意义不大,至少跑 3–5 次取最小值(排除缓存预热、TLB miss 等偶然干扰)
auto start = std::chrono::steady_clock::now();
// volatile dummy = do_work(); // 防优化
do_work();
auto end = std::chrono::steady_clock::now();
auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count();

Windows 下 QueryPerformanceCounter 还有必要手撸吗?

没必要。除非你卡在非常老的环境(如 VS2010 + Windows XP),且明确测出 steady_clock 精度不足(比如只到 15ms),否则手调 QueryPerformanceCounter 只会增加维护成本和出错概率。

容易踩的坑:QueryPerformanceFrequency 返回值可能为 0(极罕见但存在),或在某些虚拟机里频率不稳定;LARGE_INTEGER 直接相减若没处理符号位,会导致巨大正数;不同 CPU 核心的 TSC 不同步(启用 QPC 时系统已处理,但旧驱动可能失效)。

  • 现代 MSVC(2015+)和 libc++/libstdc++ 都已正确封装 QPC,steady_clock::now() 就是它
  • 若真要手撸,务必检查 QueryPerformanceFrequency(&freq) 返回值,且用 __emul64 或 Int128 处理 64×64 除法避免截断
  • 不要用 GetTickCount64 替代——它只有 1–15ms 分辨率,且非单调(可能回绕)

跨平台构建时要注意的 ABI 和编译器差异

steady_clock 的实现细节由标准库决定,不是语言本身保障的。同一份代码在 GCC、Clang、MSVC 下行为一致,但若混用不同标准库(如 Linux 上用 libc++ 编译却链接 libstdc++ 的 .so),时钟对象可能不兼容。

性能影响:所有主流实现都是无锁、寄存器级指令(RDTSC、cntvct_el0 等),调用开销稳定在 20–50 纳秒,远低于任何 syscall。

  • 确保 CMake 中 set(CMAKE_CXX_STANDARD 17) 或更高,C++11 是底线,但 C++17 起 steady_clock 必须是单调的
  • Android NDK r21+ 默认用 libc++,旧版本可能 fallback 到不稳定的 clock_gettime(CLOCK_MONOTONIC),需显式指定 -DANDROID_STL=c++_shared
  • 嵌入式平台(如 ARM Cortex-M)若无硬件定时器支持,steady_clock 可能退化为毫秒级 tick,此时得查 BSP 是否提供 HAL_GetTick 类接口

真正麻烦的从来不是选哪个时钟,而是确保待测代码不被优化、内存访问不被重排、CPU 频率不动态缩放(需要 sudo cpupower frequency-set -g performance)、以及每次测量都清除 cache 和分支预测器状态——这些比时钟本身难控制得多。

相关文章

数码产品性能查询
数码产品性能查询

该软件包括了市面上所有手机CPU,手机跑分情况,电脑CPU,电脑产品信息等等,方便需要大家查阅数码产品最新情况,了解产品特性,能够进行对比选择最具性价比的商品。

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

Flowith
Flowith Hot

Flowith是一款基于画布和智能体工作流的 AI 协作工作空间。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

相关专题

更多
counta和count的区别
counta和count的区别

Count函数用于计算指定范围内数字的个数,而CountA函数用于计算指定范围内非空单元格的个数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

3908

2023.11.20

c++中volatile关键字的作用
c++中volatile关键字的作用

本专题整合了c++中volatile关键字的相关内容,阅读专题下面的文章了解更多详细内容。

854

2025.10.23

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

3248

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

5469

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

3909

2025.12.29

java接口相关教程
java接口相关教程

本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

506

2026.01.19

windows查看端口占用情况
windows查看端口占用情况

Windows端口可以认为是计算机与外界通讯交流的出入口。逻辑意义上的端口一般是指TCP/IP协议中的端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等等。怎么查看windows端口占用情况呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

3479

2023.07.26

查看端口占用情况windows
查看端口占用情况windows

端口占用是指与端口关联的软件占用端口而使得其他应用程序无法使用这些端口,端口占用问题是计算机系统编程领域的一个常见问题,端口占用的根本原因可能是操作系统的一些错误,服务器也可能会出现端口占用问题。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

3018

2023.07.27

Go-Zero API开发使用教程
Go-Zero API开发使用教程

本专题聚焦Go-Zero的API开发,拆解.api描述文件的语法结构、路由与分组定义、参数绑定与校验规则,说明统一响应体、JWT鉴权、跨域与接口文档生成的落地方式,并给出网关聚合与接口测试的实践建议。

20

2026.11.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn