0

0

如何使用c++的std::chrono库进行精确的时间测量? (高精度计时)

穿越時空

穿越時空

发布时间:2026-01-16 11:33:23

|

108人浏览过

|

来源于php中文网

原创

不能直接当作“最高精度”用。它只是标准库中理论上精度最高的时钟,实际精度取决于平台和硬件;Windows 通常退化为 steady_clock,Linux 多为 CLOCK_MONOTONIC_HR;需结合 is_steady 和 period 判断;实操优先用 steady_clock 测耗时,避免 system_clock。

如何使用c++的std::chrono库进行精确的时间测量? (高精度计时)

std::chrono::high_resolution_clock 是否真能提供“最高精度”?

不能直接当作“最高精度”用。它只是标准库中定义的、理论上精度最高的时钟,但实际精度取决于平台和硬件。Windows 上通常退化为 std::chrono::steady_clock(基于 QueryPerformanceCounter),Linux 上多数是 CLOCK_MONOTONIC_HR,但 glibc 旧版本可能 fallback 到 CLOCK_MONOTONIC。关键看 std::chrono::high_resolution_clock::is_steady 返回值,以及其 period::numperiod::den —— 比如 std::nano 表示纳秒级分辨率,但不等于能稳定测出 1ns 差异。

实操建议:

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

  • 优先用 std::chrono::steady_clock:单调、无跳变、适合测量耗时,绝大多数场景更可靠
  • 避免用 std::chrono::system_clock 测间隔:它反映墙上时间,受系统时钟调整影响(NTP 同步、手动改时间都会导致负值或跳变)
  • 检查实际分辨率:
    std::cout << std::chrono::high_resolution_clock::period::num << "/"
              << std::chrono::high_resolution_clock::period::den << "\n";
    若输出 1/1000000000,说明标称纳秒级;但真实抖动可能在微秒量级

如何正确测量一段代码的执行时间(避免常见误差)?

最常见错误是把 clock::now() 调用本身计入测量范围,或忽略编译器优化导致代码被删减。正确做法是强制防止优化 + 多次采样取最小值(排除中断、缓存未命中等噪声)。

实操建议:

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

  • volatileasm volatile("" ::: "memory") 防止编译器重排或省略待测代码
  • 至少运行 3–5 次,取最小耗时 —— 最小值最接近“纯代码开销”,排除调度延迟、TLB miss 等偶然因素
  • 时间差必须用同一时钟的两次 time_point 相减,不要跨时钟类型转换
  • 避免用 .count() 直接转整数再除法算毫秒——先转 duration 再用 duration_cast

示例(测一个简单循环):

PaperFake
PaperFake

AI写论文

下载
auto start = std::chrono::steady_clock::now();
for (int i = 0; i < 1000; ++i) {
    volatile int x = i * i; // 防优化
}
auto end = std::chrono::steady_clock::now();
auto dur = end - start;
auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(dur).count();
std::cout << "cost: " << ns << " ns\n";

std::chrono::duration_cast 的截断行为与溢出风险

duration_cast 是向零截断(truncation),不是四舍五入。比如 999 纳秒转微秒得 0,1001 纳秒才得 1。更危险的是跨数量级转换时隐式溢出 —— 如把小时级 duration 强转成 nanoseconds,可能超出 long long 范围。

实操建议:

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

  • 始终用目标精度的 duration_cast,例如要毫秒就 cast 到 milliseconds,别先转 nanoseconds 再自己除 1e6
  • 对长时间运行的测量,优先用 secondsmilliseconds 存储,避免纳秒累积溢出
  • 若需高精度且长时长,拆成两部分:先用 duration_cast<seconds></seconds> 取整秒,再用 duration_cast<nanoseconds></nanoseconds> 取余下纳秒,分别处理

跨线程或信号上下文里调用 now() 是否安全?

是线程安全的,steady_clock::now()high_resolution_clock::now() 都是无状态、无锁的函数调用,可安全用于多线程、信号处理函数(前提是信号处理函数中只做简单计时,不分配内存或调用非 async-signal-safe 函数)。

但要注意:

  • 信号处理函数中调用 std::chrono::steady_clock::now() 是允许的(POSIX 允许的 async-signal-safe 函数子集之外,C++ 标准未明确定义,但主流实现如 libstdc++/libc++ 均基于系统调用封装,实际可用)
  • 不要在信号处理函数里用 std::coutstd::string 或任何可能触发 malloc 的操作
  • 若需记录时间戳供主线程消费,用原子变量或 lock-free ring buffer 存储 time_point::time_since_epoch().count() 值(它是 duration,可安全复制)

真正影响精度的从来不是库接口,而是你是否关掉了 CPU 频率缩放、是否绑定了 CPU 核心、是否在虚拟机里跑 —— 这些比选哪个 clock 更关键。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1031

2023.08.02

counta和count的区别
counta和count的区别

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

203

2023.11.20

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

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

76

2025.10.23

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

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

1954

2023.10.19

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

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

658

2025.10.17

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

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

2401

2025.12.29

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

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

47

2026.01.19

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

765

2023.08.10

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

26

2026.03.13

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 10.6万人学习

Git 教程
Git 教程

共21课时 | 4.2万人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号