【问题标题】:How to give an emulation the right speed? [duplicate]如何为仿真提供正确的速度? [复制]
【发布时间】:2014-09-13 22:33:27
【问题描述】:

我想为运行在 600 左右千赫兹的特别慢的 CPU 编写一个模拟器。如果我以天真的方式为 CPU 编写一个模拟器(即一次模拟一条指令而没有其他任何东西),那么模拟速度将比 600 kHz 快得多。

无论主机的速度如何,如何对模拟器进行编程以以正确的速度模拟 CPU?现实世界的模拟器通常使用什么技术来做到这一点?如何避免抖动减慢仿真速度?

【问题讨论】:

  • 你在说什么模拟器? qemu,FPGA等?我的意思是,您将为这个模拟器使用哪种编程环境?
  • 典型技术(使用慢定时器来模拟每秒 10 次 6k 周期)只能“平均”工作并且有很多抖动,所以我认为这里还不够好?
  • @SamProtsenko 我的具体用例是为在 POSIX 操作系统上运行的 8 位 CPU(想想家用计算机)编写一个模拟器。
  • @harold 我不确定标准技术是什么,研究也没有发现任何有趣的东西。您介意在答案中详细说明标准技术,以便我可以投票并可能奖励赏金吗?
  • @FUZxxl 所以它只是你自己用 C 语言编写并使用 POSIX API 的用户空间应用程序,对吗?您将使用哪个操作系统(例如 Linux、FreeBSD)?还有哪个内核版本?

标签: emulation slowdown cpu-speed device-emulation jitter


【解决方案1】:

在典型的平台上,唯一可用的“周期性事件”是不准确的和低频的,当然不像 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 的字符串指令,它们实际上是通过分支返回并重新执行自身来循环的)。

【讨论】:

  • 这听起来很明智。一些系统使用精确定时的中断来播放声音。我知道这不会通过您描述的仿真方法重现。在我的用例中,我可以模拟以不同方式发出声音的部分,但是有什么技巧可以根据精确的时间来获得这些东西吗?
  • @FUZxxl 那里变得更棘手了,我见过一种方法将“外部事件”标记为它们将具有的精确时间(基于循环计数器),然后它们就像它们发生一样被处理当时。但这并不一定适用于所有事情
  • @harold 抢占怎么样?你的方法应该考虑到它吗?我的意思是,如果我们知道调度程序的time slice 值(我们可以通过sched_rr_get_interval() 获得)——我们是否需要在计算中使用这个值,以便模拟 CPU 的一个周期不会被调度程序中断?
  • @SamProtsenko 经过的时间将反映这一点并分配更大的预算,这将导致时间上的所有波动(这通常是不准确的)
猜你喜欢
  • 2016-08-26
  • 2010-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-25
  • 2019-04-09
  • 1970-01-01
相关资源
最近更新 更多