【问题标题】:How to run a loop at a specific rate in C (in emulation)如何在 C 中以特定速率运行循环(在仿真中)
【发布时间】:2019-06-13 08:10:09
【问题描述】:

我现在正在编写一个模拟器作为一个副项目,我想以适当的速度模拟我选择的机器作为原始硬件。我的系统应该更强大,以至于执行一条指令的时间可以忽略不计,所以如果我只有一个函数,比如tick,它执行一条指令,它会运行得太快。

我想知道在 C 中是否有任何方法可以在某个给定的时间间隔(以 MHz 为单位)调用函数。就上下文而言,我是在 mac 上编写的,所以任何 POSIX 或 OS X SDK 中的东西都可以工作(我查看了 libdispatch 但什么都看不到)。

最好让一个循环运行并计算自上次循环以来的时间增量?这似乎相当低效(抢占也可能成为这里的一个因素)。这样做的其他方法是什么?谢谢。

【问题讨论】:

    标签: c macos loops emulation grand-central-dispatch


    【解决方案1】:

    由于其他任务进入系统调度程序等,非 RTOS 上的时间非常不稳定。想象一下,如果在你的模拟过程中,你打开一个网络浏览器窗口,你所有的时间都会消失。

    因此,也许您可​​以采取不同的方法:不要依赖系统的时间,而也要使用模拟时间。

    由于您也在模拟内核,处理所有指令,因此您知道您执行了多少指令,因此您可以计算模拟系统已执行的实际滴答数。然后,您可以使用此刻度来计算系统上的时间,更新您可能模拟的任何硬件计时器中断等等......

    某个特定功能会比现实生活中更快吗?没关系,您的系统会知道 XX 滴答已过去,并会执行任何中断或基于此的任何操作。

    使用这种方法,真实秒数将不等于模拟秒数,但您的模拟将始终相同,与其他应用程序或系统调度问题无关。

    此外,如果您想与实时同步,您可以不时(即在执行任何函数或异常返回后)将您的刻度与实时同步,只需暂停执行下一条指令。

    最后,看看question,因为他们提供了很多值得一读的仿真信息。特别是,我上面描述的方法将对应于该链接上描述的“解释”方法。

    【讨论】:

      【解决方案2】:

      如果操作系统不是实时操作系统,恐怕很难(甚至不可能)在托管系统上存档。 OS X 不是实时系统,您的时间将相当“随机”,因为您的应用程序将由系统调度程序提供执行时间,并且它不会控制 CPU 执行。

      上下文切换时间和延迟将不是这里的主要问题。

      如果您模拟目标系统行为,您还需要关联目标系统指令时序,并在模拟器执行期间(根据当前经过的时间)修改目标指令的模拟速度

      【讨论】:

        【解决方案3】:

        这很难准确,因为 OS X 不是实时系统。如果不需要绝对精度,那么我将使用一个间隔计时器,该计时器每隔1/n 到期,例如以“n per seconds”的速度,然后在过期处理程序中执行tick

        起点是 POSIX setitimer() 并在信号处理程序中调用 tick

        【讨论】:

          【解决方案4】:

          使用clock_gettime()nanosleep() 是可行的方法。其他一些定期调用您的函数的机制肯定会比这慢。您甚至可以考虑循环和计数循环而不是使用nanosleep()。考虑一些数字:

          在 1 MHz 时,您的函数有 1 微秒的时间运行。 在 10 MHz 时,您的函数有 100 纳秒的时间运行。

          一些关于系统调用和上下文切换时序的实验数据:https://blog.tsunanet.net/2010/11/how-long-does-it-take-to-make-context.html

          所以看起来系统调用超过 50 纳秒,上下文切换超过 1 微秒。除了您自己在同一进程中的代码之外,调用您的函数的其他一些事情可能会花费“太长时间”。

          【讨论】:

          • 仅供参考:macOS clock_gettime() 的分辨率为 1 微秒(请参阅 clock_getres())。因此,对于大于 1 MHz 的频率,您不能真正使用这些设施 - 否则您将获得不稳定的行为。
          猜你喜欢
          • 1970-01-01
          • 2018-02-21
          • 1970-01-01
          • 2023-01-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多