如何以编程方式模拟较低的处理器频率?

发布于 2024-11-04 19:01:05 字数 142 浏览 4 评论 0原文

我有兴趣在我的 2GHz+ 处理器上以特定频率(例如 25MHz)运行程序。我能想到的执行此类操作的唯一方法是使用微秒精度睡眠函数,但我不确定如何计算线程应睡眠多长时间才能匹配特定频率。有什么建议或其他想法吗?我在 X86 Linux 操作系统上用 C 语言执行此操作。

I'm interested in running a program at a specific frequency (like 25MHz) on my 2GHz+ processor. The only method I can think of for doing something like this is using a microsecond precision sleep function, but I am unsure of how to calculate how long the thread should sleep for in order to match a specific frequency. Any tips or other ideas? I'm doing this in C on an X86 Linux OS.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

余罪 2024-11-11 19:01:05

这里有几个问题。这是您想要模拟的第一个内容。现代处理器的时钟频率为 2Ghz,但指令采用流水线方式,因此单个指令可能需要 10-30 个时钟才能完成。通过在线程中放置睡眠,您会破坏管道。第二个是你想要模拟的粒度。您是否需要具有指令级时序,我们可以通过在函数之间放置一些空间来伪造它吗?

我的最后一个想法是,您可能不想模拟以 25Mhz 运行的现代处理器,而是模拟嵌入式设备上的某种类型的 ARM 芯片。如果是这种情况,市场上已经有针对大多数此类芯片的非常好的模拟器。将代码编译为目标芯片的本机指令,它们使用现有的模拟器(如果可用)。


编辑

据我现在了解,您希望每秒在虚拟处理器上执行 25M 次指令。我可能会尝试一种适应性方法。你有很多时间在指令之间“搞乱”。首先在每条指令之间放置一些间距,睡眠可能会起作用。请注意,在数组中,当每个虚拟时钟启动时,要尽可能精确地保持最近 25、100 或 1000 个周期的滚动平均值。如果平均值上升到 25Mhz 以上,则开始添加更多空间。如果太慢则减少空间。

正如我最初所说,计算一条指令在现代处理器上花费的时间是非常困难的。第一组指令可能运行得有点太快或太慢,但是像这样的技术应该使其尽可能接近正确的速度,就像类似硬件实现上的典型振荡器一样。

There are a couple of problems here. This first what you are trying to simulate. Modern processors clock at 2Ghz but pipeline instructions so an individual instruction may take 10-30 clocks to finish. By putting a sleep in the thread you break the pipe-line. The second is how granular you want to have you simulation. Do you need to have instruction level timing of can we fake it by putting some space between functions.

My last thought is that you are likely not wanting to simulate a modern processor running at 25Mhz, but some type of ARM chip on an embedded device. If this is the case there are very good simulators for most of these chips already on the market. Compile your code to native instructions for your target chip, them use an already available simulator if one is available.


Edit:

So as I now understand it you want to execute an instruction on of a virtual processor 25M times a second. What I might try is an adaptive approach. You have lots of time to "mess around" between instructions. start by putting some spacing, sleep will probably work, between each instruction. Note in an array with as much precision as possible when each virtual clock started keep a rolling average of say the last 25, 100 or 1000 cycles. If the average rises above 25Mhz start adding more space. If it is too slow reduce the space.

As I said originally, it is very hard to calculate the amount of time an instruction takes on a modern processor. The first set of instructions may run a little too fast or slow, but a technique like this should keep it as close to the right speed as a typical oscillator on a comparable hardware implementation would.

作业与我同在 2024-11-11 19:01:05

我建议采用事件驱动架构:在每个 STEP (1/hz) 上,触发 1 个指令操作。

I would suggest an event-driven architecture: on each STEP (1/hz), fire 1 instruction operation.

红玫瑰 2024-11-11 19:01:05

我会简单地批量运行模拟。例如,您可以运行 25 万个周期,然后在剩余的 10 毫秒间隔内休眠。您可以调整模拟看到的时钟视图,使其完全透明,除非它与需要以特定速率连接的某种外部硬件连接(在这种情况下,这将成为一个更加困难的问题)。

I would simply run the simulation in bursts. For example you could run 250 thousand cycles, then sleep for the remainder of a 10 msec interval. You could adjust the view of the clock that the simulation sees to make this completely transparent, unless it's interfacing with some sort of external hardware that needs to be interfaced with at a particular rate (in which case this becomes a much more difficult problem).

瘫痪情歌 2024-11-11 19:01:05

综上所述,如果您在用户模式下尝试以特定频率模拟虚拟处理器,则应该通过睡眠调用或对处理 CPU 指令的线程实现某种手动“调度”。更高级的功能和特性,例如 Windows 中的光纤。您应该注意的一个警告是,某些操作系统睡眠调用不会在您指定的确切时间内睡眠,因此您可能需要添加额外的代码来校准计算机之间的偏差,以便更接近目标频率。通常,您将无法准确地安排虚拟处理器以稳定的 25 MHz 运行(更有可能是 22-28 MHz)。不管怎样,我同意内森和突发的想法。祝您无论走哪条路都好运!

To sum up what the above answers have said, if you are in user-mode attempting to emulate a virtual processor at a specific frequency, you should implement some sort of manual "scheduling" of the thread that processes CPU instructions either via sleep calls or more advanced functions and features like fibers in Windows. A caveat you should look out for is that some OS sleep calls do not sleep for the exact amount of time you specify, so you may have to add additional code to calibrate the deviation from computer to computer in order to get closer to the target frequency. More often than not, you will not be able to accurately schedule your virtual processor to run at a steady 25 MHz (22-28 MHz is more likely). Anyways, I agree with both Nathan and the burst idea. Good luck in which ever path you use!

苏璃陌 2024-11-11 19:01:05

对于虚拟机来说,一切都是虚拟的,包括时间。例如,在 123 实际秒中,您可以模拟 5432 虚拟秒的处理。测量虚拟时间的常见方法是每次模拟虚拟指令时增加“周期数”计数器(或添加一些内容)。

您时不时地会尝试将虚拟时间与实时时间同步。如果虚拟时间比实时时间提前太多,您可以插入一个延迟,让实时时间赶上。如果虚拟时间落后于实时时间,那么你需要找到一些放慢速度的借口。根据模拟的架构,您可能无能为力;但对于某些架构,有电源管理功能,例如热节流(例如,您可以假装虚拟 CPU 变热并且运行速度较慢以冷却)。

您可能还想要一个事件队列,其中不同的模拟设备可以说“在某个特定时间将发生某个事件”;这样,如果模拟的 CPU 空闲(等待事件发生),您可以跳到下一个事件发生的时间。这为虚拟机提供了一种自然的方式来赶上运行缓慢的情况。

下一步是确定时间重要的位置,并且仅将这些特定位置的虚拟时间与实时时间同步。如果模拟机器正在执行繁重的处理并且不执行任何外部观察者可见的操作,则外部观察者无法判断虚拟时间是否接近实时。当虚拟机确实执行外部观察者可见的操作(例如发送网络数据包、更新视频/屏幕、发出声音等)时,您首先将虚拟时间与实时时间同步。

除此之外,使用缓冲将模拟器内部发生的事情与外部观察者可见的事情分离。举一个(夸张的)例子,假设仿真机认为现在是早上 8:23,它想要发送一个网络数据包,但实际上只是早上 8:00。简单的解决方案是延迟仿真 23 分钟,然后发送数据包。这听起来不错,但是如果(在虚拟机发送数据包之后)模拟器难以跟上实时速度(由于真实计算机上运行的其他进程或任何其他原因),模拟器可能会落后,并且您可能会遇到维护问题虚拟时间与真实时间相同的错觉。或者,您可以假装数据包已发送,并将数据包放入缓冲区并继续模拟其他事物,然后稍后发送数据包(实际上是现实世界中的早上 8:23)。在这种情况下,如果(在虚拟机发送数据包之后)模拟器难以跟上实时速度,您还有 23 分钟的余地。

For a virtual machine, everything is virtual, including time. For example, in 123 real seconds, you might emulate 5432 virtual seconds of processing. A common way of measuring virtual time is to increment (or add something to) a "number of cycles" counter each time a virtual instruction is emulated.

Every now and then you'd try to synchronise virtual time with real time. If virtual time is too far ahead of real time you insert a delay to let real time catch up. If virtual time is behind real time then you need to find some excuse for the slow-down. Depending on the emulated architecture there may be nothing you can do; but for some architectures there's power management features like thermal throttling (for e.g. maybe you can pretend the virtual CPU got hot and is running slower to cool down).

You also probably want to have an event queue, where different emulated devices can say "at some specific time some event will occur"; so that if the emulated CPU is idle (waiting for an event to occur) you can skip ahead to when the next event will happen. This provides a natural way for the virtual machine to catch up if it's running slow.

The next step is to determine places where timing matters and only synchronise virtual time with real time at those specific places. If the emulated machine is doing heavy processing and not doing anything that is visible to an outside observer, then an outside observer has no way to tell if virtual time is close to real time or not. When the virtual machine does do something that is visible to an outside observer (e.g. send a network packet, update the video/screen, make a sound, etc) you synchronise virtual time with real time first.

The step beyond that is using buffering to decouple when things occur inside the emulator from when they're visible to an outside observer. For an (exaggerated) example, imagine the emulated machine thinks it's 8:23 in the morning and it wants to send a network packet, but it's actually only 8:00 in the morning. The simple solution is to delay emulation for 23 minutes and then send the packet. That sounds good, but if (after the virtual machine sends the packet) the emulator struggles to keep up with real time (due to other processes running on the real computer or any other reason) the emulator can fall behind and you can have problems maintaining the illusion that virtual time is the same as real time. Alternatively you could pretend the packet was sent and put the packet into a buffer and continue emulating other things, and then send the packet later (when it actually is 8:23 in the morning in the real world). In this case, if (after the virtual machine sends the packet) the emulator struggles to keep up with real time you've still got 23 minutes of leeway.

终难愈 2024-11-11 19:01:05

请参阅 Fracas CPU 模拟器,了解以下方法:这。作者在 Heteropar 研讨会上介绍了这一点,该研讨会是 EUROPAR 2010。它们实质上修改了操作系统调度程序,以允许用户程序仅使用实际 CPU 频率的一小部分。

See the Fracas CPU emulator for an approach to this. The authors presented on this at the Heteropar workshop, a part of EUROPAR 2010. They essentially modify the OS scheduler to permit usage of only fractions of the real CPU freq to be used by user programs.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文