You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用std::chrono实现稳定更新循环的帧抖动问题咨询

关于std::chrono实现固定间隔循环的抖动问题解答

代码逻辑评估

你的实现逻辑不存在bug,是固定间隔循环的标准正确写法:

  • 选用std::chrono::steady_clock单调时钟,避免系统时间调整导致的间隔错误
  • 采用「目标时间累加」+sleep_until的逻辑,而非每次调用sleep_for(100ms),避免了工作逻辑耗时带来的误差累计问题
bool firstUpdate = true;
std::chrono::time_point<std::chrono::steady_clock> lastUpdateTime;
std::chrono::time_point<std::chrono::steady_clock> lastUpdateProf;

while (true)
{
    if (firstUpdate)
    {
        lastUpdateTime = std::chrono::steady_clock::now();
        firstUpdate = false;
    }

    lastUpdateTime = lastUpdateTime + std::chrono::milliseconds(100);

    // Do the work, generate data and send data
    ....

    // Sleep if necessary 
    std::this_thread::sleep_until(lastUpdateTime);

    // Additional profiling of frame duration
    auto now = std::chrono::steady_clock::now();
    std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(now - lastUpdateProf).count() << std::endl;
    lastUpdateProf = now;
}

抖动表现合理性说明

你测得的±2ms抖动完全属于Windows 10非实时桌面平台的正常预期,主要有以下几个原因:

  • Windows为通用桌面操作系统,不提供硬实时调度保证,你的用户态线程随时可能被更高优先级的系统线程、硬件中断处理程序、其他后台进程抢占CPU,导致唤醒延迟
  • 默认情况下Windows系统的定时器时钟粒度为10~15.6ms,即便sleep_until指定了精确的唤醒时间,操作系统也只会在时钟中断触发时检查线程唤醒条件,天然存在毫秒级的调度误差
  • 标准库的std::this_thread::sleep_until底层依赖系统定时器实现,本身就只提供最佳努力的唤醒保证,不承诺绝对精度

可选优化方案

如果需要进一步降低抖动,可以采取以下Windows平台专属优化手段:

  • 调用Win32 API timeBeginPeriod(1)将系统定时器精度临时提升到1ms,使用完成后调用timeEndPeriod(1)恢复系统默认设置,可将抖动压缩到±1ms左右
  • 适当提升工作线程的调度优先级,例如调用SetThreadPriority将线程优先级设置为THREAD_PRIORITY_HIGHEST,减少被其他线程抢占的概率
  • 优化工作逻辑,避免在循环内调用可能产生阻塞的IO、锁等待操作,减少不可控的耗时波动

内容的提问来源于stack exchange,提问作者Ben

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 08:45:04