【问题标题】:How would one programmatically simulate lower processor frequencies?如何以编程方式模拟较低的处理器频率?
【发布时间】:2011-08-17 04:02:44
【问题描述】:

我有兴趣在我的 2GHz+ 处理器上以特定频率(如 25MHz)运行程序。我能想到的唯一方法是使用微秒精度睡眠功能,但我不确定如何计算线程应该睡眠多长时间以匹配特定频率。任何提示或其他想法?我在 X86 Linux 操作系统上用 C 语言做这个。

【问题讨论】:

  • 您这样做的目标/“用例”是什么?您是否尝试在较低速度下测量性能?
  • 我做了一个虚拟处理器,我想以特定频率运行它。

标签: c assembly x86 cpu simulation


【解决方案1】:

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

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

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

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

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

【讨论】:

    【解决方案2】:

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

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


    编辑

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

    正如我最初所说,很难计算一条指令在现代处理器上花费的时间。第一组指令的运行速度可能有点太快或太慢,但是像这样的技术应该让它保持在与可比硬件实现上的典型振荡器一样接近正确的速度。

    【讨论】:

    • 这种回答没有帮助。作者问的是如何购买现有软件,而不是在哪里购买。
    • Subwar,当我写这个答案时,评论“我做了一个虚拟处理器......”还没有发布。我回答了我认为被问到的问题,即如何模拟以 25Mhz 运行 2Ghz X86 处理器。第二段是猜测,这并不是他想要做的。事实证明我猜对了一半。他确实想模拟一个不同的处理器,而不是一个预先存在的处理器。
    • 我开枪了。道歉朋友:)
    【解决方案3】:

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

    【讨论】:

    • 要计算秒数,您应该使用一些程序集来计算一些虚拟代码(可能会被执行的代码)的执行时间。然后推导出某种算法(通过实验),将执行代码所花费的时间与执行的虚拟代码的大小联系起来。您可以使用此算法进一步计算运行虚拟处理器代码所需的时间,或者更好的是,在您的仿真循环中动态地重新使用该算法来确定休眠多长时间(校准因素)。
    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

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

      【讨论】:

        【解决方案6】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-02-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-02-20
          • 2012-07-27
          • 1970-01-01
          • 2010-11-04
          相关资源
          最近更新 更多