【问题标题】:what is Interruptible-restartable instructions in ARM cortex m0/m0+什么是 ARM cortex m0/m0+ 中的可中断重启指令
【发布时间】:2015-09-15 20:06:28
【问题描述】:


我目前正在阅读 ARM 网站上的 ARM Cortex M0+ 用户指南,如下所示 http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0662b/CHDBIBGJ.html

在用户手册中,提到了以下段落:

可中断重启指令
可中断重启指令是 LDM、STM、PUSH、POP 以及在 32 周期乘法器实现中的 MULS。当在执行这些指令之一期间发生中断时,处理器将放弃执行该指令。处理完中断后,处理器从头开始重新执行指令。

我无法理解可重启指令的工作原理?有人可以举例说明可中断重启指令的不同阶段(获取、解码和执行)吗?中断来临时指令流水线会发生什么?

【问题讨论】:

  • 这里没有什么花哨的,CPU 不保存部分状态和恢复或任何东西。相反,如果一个中断到达,它只是停止而不推进程序计数器,迫使指令在从中断返回时重新执行。请注意,内部寄存器用于缓冲,例如在不破坏输入的情况下读取/写入指针和乘法结果。这种方案的结果是STM 不是原子的,并且中断处理程序可能会看到部分写入。同样,具有副作用的 I/O 寄存器可能会被多次访问。
  • 这些指令可能/确实会消耗大量时间,因此处理器设计选择是:等待它们完成并产生延迟,以某种方式在中间保存状态并完成部分完成的指令,或者放弃指令并重新开始。第一个和最后一个选项很简单,从延迟的角度来看,后者是性能最好的(肯定会消耗更多的周期)。

标签: assembly arm cpu-architecture cortex-m


【解决方案1】:

对于 LDM,执行阶段实际上是多个周期(每个寄存器至少一个周期)。

这就是简单的获取/解码/执行模型开始崩溃的地方 - 执行实际上是一个非平凡的状态机,它通常可以表示单个周期,但有一些“特殊' 操作。

对于 Cortex M,即使在基本级别上,当异常发生时,除了将 fetch 指向异常处理程序并在中断当前指令后等待执行变得空闲之外,还有很多工作要做.

在硬件层面理解不可中断和可重启指令的关键部分是它们由架构寄存器控制,并且没有很多中间状态。如果有中间状态,则存储在 EPSR.ICI 中。还有一些中间寄存器存储用于诸如乘法中间结果之类的事情,因此可以恢复架构寄存器而不会损坏。

至于为什么架构致力于支持可重新启动或可继续的指令(如 cmets 中所述),这专门用于改善中断延迟(这是 Cortex-M 的关键之一特征)。对于单个加载或存储,程序员通常有足够的控制权,不会在中断延迟很关键时冒过长的数据接口停顿的风险,并且对 12 个周期的延迟不应该有太大的影响。对于加载/存储倍数,延迟可能很重要(从程序的角度来看,当异常挂起时,堆栈推送之类的东西没有价值,因为处理程序本身会处理即时的上下文保存要求)。由于这些处理器通常只有一个数据存储器接口,因此微码异常堆栈不能与完成加载/存储多个剩余节拍并行发生。

需要权衡多周期指令,即简单地放弃、暂停以稍后继续的指令,以及必须完成的指令。作为总线接口的结果,一旦传输开始,它必须完成。可继续的指令不是原子的,可重新启动的指令可能会导致重复访问同一地址(因此在写入外设 fifo 等时必须避免这些)。通过保持良好的中断性能,所有这些额外的复杂性对于目标应用程序来说仍然是合理的,并且通常不需要程序员担心精确的细节。另一种方法是在任何地方使用单独的 LDM,从代码密度的角度来看,这是低效的(并且可能的性能取决于 uArch/系统)。

【讨论】:

  • 我认为这个答案将受益于陈述 doynax 和 old_timer 在 cmets 中写的基本知识:不等待指令完成是中断延迟的胜利。
  • 是的,看起来不错。我可能会说,可中断指令让您可以在许多寄存器上使用ldm 以获得高代码密度,没有损害中断延迟的风险。如果使用该功能,您必须仔细控制所有代码生成,以将最坏情况下的中断延迟降至最低。
猜你喜欢
  • 2015-07-05
  • 2020-12-24
  • 2016-06-10
  • 2018-01-29
  • 2021-10-06
  • 2011-07-26
  • 1970-01-01
  • 2016-10-23
  • 1970-01-01
相关资源
最近更新 更多