我想为运行在 600 左右千赫兹的特别慢的 CPU 编写一个模拟器。如果我以天真的方式为 CPU 编写一个仿真器(即一次仿真一条指令而没有其他任何东西),仿真将比 600 千赫兹快得多。
无论主机的速度如何,如何对模拟器进行编程以以正确的速度模拟 CPU?现实世界的模拟器通常使用什么技术来做到这一点?如何避免抖动减慢仿真速度?
我想为运行在 600 左右千赫兹的特别慢的 CPU 编写一个模拟器。如果我以天真的方式为 CPU 编写一个仿真器(即一次仿真一条指令而没有其他任何东西),仿真将比 600 千赫兹快得多。
无论主机的速度如何,如何对模拟器进行编程以以正确的速度模拟 CPU?现实世界的模拟器通常使用什么技术来做到这一点?如何避免抖动减慢仿真速度?
在一个典型的平台上,唯一可用的“周期性事件”是不准确的和低频的,当然不像 0.6MHz。但是使用“慢”计时器(可能是 100Hz 左右),您可以“运行许多短冲刺”,在这之间有足够的时间“休息”,平均而言,您正在模拟每秒的正确周期数。通常可以相当准确地测量时间,因此您可以在每个“冲刺”中准确模拟正确的周期数。
在高层次上,这可能看起来像这样:
int cycle_budget = 0;
time last_sprint = something;
// on timer fire
cycle_budget += (current_time - last_sprint) * clock_rate;
last_sprint = current_time;
while (cycle_budget >= slowest_instruction)
tick(); // emulates one instruction, subtracts from cycle_budget
有一些明显的变化,例如,您可以让预算变为负数,而不是测试是否有足够的资金来运行慢速指令。或者您可以对指令进行解码,然后测试是否有足够的预算来运行它。这一切都假设一条指令不会花很长时间,但据我所知,这从来都不是问题(即使是像 z80 的字符串指令,它们实际上是通过分支返回并重新执行自身来循环的)。