不同计算机上的时钟时序变化
Clock timing changes on different computers
我正在 github 上开发 DMG-01(A.K.A gameboy 1989)的实现。
我已经实现了 APU 和 PPU,在我的电脑(和我朋友的电脑)上(几乎)完美的计时。
但是,当我 运行 在我朋友的一台电脑上使用模拟器时,它 运行 是我或我其他朋友的 两倍。
同步时钟的代码(在 gameboy 和 运行ning 上的 pc 之间)如下:
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),但我不明白为什么会这样。
谢谢!
我想你可能 运行 陷入了 <chrono>
的幕后。
表达式:
clock::now() + one_clock_period
有问题。 clock
是 high_resolution_clock
,通常具有 nanoseconds
分辨率。 one_clock_period
的单位是 1/4'194'304
。结果表达式将是 time_point
,period
为 1/8'192'000'000'000
。
使用带符号的 64 位整数类型,max()
这样的精度略超过 13 天。因此,如果 clock::now()
returns .time_since_epoch()
大于 13 天,_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})};
我正在 github 上开发 DMG-01(A.K.A gameboy 1989)的实现。 我已经实现了 APU 和 PPU,在我的电脑(和我朋友的电脑)上(几乎)完美的计时。 但是,当我 运行 在我朋友的一台电脑上使用模拟器时,它 运行 是我或我其他朋友的 两倍。
同步时钟的代码(在 gameboy 和 运行ning 上的 pc 之间)如下:
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),但我不明白为什么会这样。 谢谢!
我想你可能 运行 陷入了 <chrono>
的幕后。
表达式:
clock::now() + one_clock_period
有问题。 clock
是 high_resolution_clock
,通常具有 nanoseconds
分辨率。 one_clock_period
的单位是 1/4'194'304
。结果表达式将是 time_point
,period
为 1/8'192'000'000'000
。
使用带符号的 64 位整数类型,max()
这样的精度略超过 13 天。因此,如果 clock::now()
returns .time_since_epoch()
大于 13 天,_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})};