不同计算机上时钟的定时更改

3

我正在我的github上实现DMG-01(即GameBoy 1989年版),涉及IT技术相关内容。 我已经在我的电脑以及朋友的电脑上实现了APU和PPU,且(几乎)完美地控制了时序。 但是,当我在其中一个朋友的电脑上运行模拟器时,它的运行速度会比我的电脑和其他朋友的电脑快两倍

用于同步游戏机和电脑时钟的代码如下:

Clock.h 头文件:

class Clock
{
// ...
public:
    void SyncClock();

private:
    /* API::LR35902_HZ_CLOCK is 4'194'304 */
    using lr35902_clock_period = std::chrono::duration<int64_t, std::ratio<1, API::LR35902_HZ_CLOCK>>;
    static constexpr lr35902_clock_period one_clock_period{1};
    using clock = std::chrono::high_resolution_clock;

private:
    decltype(clock::now()) _last_tick{std::chrono::time_point_cast<clock::duration>(clock::now() + one_clock_period)};
};

Clock.cpp文件

void Clock::SyncClock()
{
    // Sleep until one tick has passed.
    std::this_thread::sleep_until(this->_last_tick);

    // Use time_point_cast to convert (via truncation towards zero) back to
    // the "native" duration of high_resolution_clock
    this->_last_tick = std::chrono::time_point_cast<clock::duration>(this->_last_tick + one_clock_period);
}

这个函数在main.cpp中这样被调用:

int main()
{
    // ...
    while (true)
    {
        // processor.Clock() returns the number of clocks it took for the processor to run the
        // current instruction. We need to sleep this thread for each clock passed.
        for (std::size_t current_clock = processor.Clock(); current_clock > 0; --current_clock)
        {
            clock.SyncClock();
        }
    }
    // ...
}

为什么在其他计算机中,这种情况下chrono受影响的方式会不同?时间是绝对的,我能理解为什么在一个计算机上,运行模拟器会,但为什么会更快呢? 我检查了我的时钟类型(high_resolution_clock),但我不知道为什么会出现这种情况。 谢谢!


如果你检查 std::high_resolution_clockperiod 类型,这两个系统之间是否有区别? - Some programmer dude
@Someprogrammerdude 我的朋友不是很擅长编程,所以我得在他的电脑上安装Visual Studio(如果他同意的话),但无论如何,我不认为std::ratio会在两个系统之间发生变化(标准也没有定义这样的差异)。 - Noam Rodrik
你不需要安装Visual Studio,只需在程序中添加std::rationumden成员的日志记录即可。 - Some programmer dude
@Someprogrammerdude 好主意,我会尝试并在这里更新。 - Noam Rodrik
程序在sleep_until()后恢复的速度取决于系统配置。有些程序会干扰它,例如浏览器,Chrome尤其臭名昭著。为了获得一致的时间,您必须超越它们,至少像这样的程序一样不合理。调用timeBeginPeriod(1)。通过从提升的命令提示符中运行powercfg.exe /energy来获取诊断信息。 - Hans Passant
显示剩余3条评论
1个回答

5

我想你可能遇到了<chrono>底层的溢出问题。

表达式为:

clock::now() + one_clock_period

存在问题。 clockhigh_resolution_clock,通常具有纳秒精度。 one_clock_period 的单位是 1/4'194'304。所得表达式将是具有 1/8'192'000'000'000 周期的time_point

使用带符号64位整数类型,在这样的精度下进行max()计算会略微超过13天。因此,如果 clock::now() 返回> 13天的 .time_since_epoch()_last_tick 将溢出,并且有时可能为负(取决于 clock::now() 超过13天的时间)。

为了纠正这个问题,请立即尝试将 one_clock_period 强制转换为与 clock 相同的精度:

static constexpr clock::duration one_clock_period{
    std::chrono::duration_cast<clock::duration>(lr35902_clock_period{1})};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接