如何在C中以特定速率运行循环(在仿真中)

时间:2019-01-19 06:04:24

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

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

我想知道在C语言中是否有某种方法可以在给定的时间间隔(以MHz为单位)中调用函数。就上下文而言,我是在Mac上编写的,因此任何POSIX或OS X SDK都可以使用(我通过libdispatch查看,但看不到任何东西)。

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

4 个答案:

答案 0 :(得分:1)

使用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 :(得分:1)

由于其他任务进入了系统调度程序,因此非RTOS上的时间安排很不稳定。想象一下,如果在仿真过程中打开一个Web浏览器窗口,所有的时间安排都将消失。

因此,也许您可​​以采用另一种方法:不要依靠系统时间,而要使用模拟时间。

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

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

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

此外,如果您想与实时同步,则可以不时地(即在执行从函数或异常返回的任何操作之后)通过实时停止您的报价来实现实时同步。下一条指令。

最后,看看这个question,因为它们给出了很多值得阅读的仿真信息。特别地,我上面描述的方法将对应于该链接上描述的“解释”方法。

答案 2 :(得分:1)

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

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

答案 3 :(得分:-1)

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

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

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