Assembly ARM Cortex M中的ISB指令

Assembly ARM Cortex M中的ISB指令,assembly,arm,cortex-m,memory-barriers,instructions,Assembly,Arm,Cortex M,Memory Barriers,Instructions,直到现在,我使用了3个NOP来清洁管道。 最近我遇到了ISB指令,它为我实现了这一点。 查看手臂信息中心,我注意到这个命令在Cortex M0下需要4个周期,3个NOP只需要3个周期 我为什么要使用这个命令?它与3个NOP有什么不同?您应该使用ISB指令来确保管道畅通。如上所述,不同ARM处理器之间的管道可能不同,例如,M7有6级管道,而M3/4有3级管道。根据ISB M4技术参考手册,最小循环次数等于管道重新加注所需的次数 我不确定为什么这是4个周期而不是3个周期,这可能与确保分支预测逻辑正确

直到现在,我使用了3个NOP来清洁管道。 最近我遇到了ISB指令,它为我实现了这一点。 查看手臂信息中心,我注意到这个命令在Cortex M0下需要4个周期,3个NOP只需要3个周期


我为什么要使用这个命令?它与3个NOP有什么不同?

您应该使用ISB指令来确保管道畅通。如上所述,不同ARM处理器之间的管道可能不同,例如,M7有6级管道,而M3/4有3级管道。根据ISB M4技术参考手册,最小循环次数等于管道重新加注所需的次数


我不确定为什么这是4个周期而不是3个周期,这可能与确保分支预测逻辑正确有关。不管你是否希望你的代码是可移植的,我建议使用ARM提供的工作,如果他们认为你需要4个周期,那么我希望你这样做。在某些情况下,如果只有3个,可能会出现错误的操作。

您应该使用ISB指令来确保管道畅通。如上所述,不同ARM处理器之间的管道可能不同,例如,M7有6级管道,而M3/4有3级管道。根据ISB M4技术参考手册,最小循环次数等于管道重新加注所需的次数


我不确定为什么这是4个周期而不是3个周期,这可能与确保分支预测逻辑正确有关。不管你是否希望你的代码是可移植的,我建议使用ARM提供的工作,如果他们认为你需要4个周期,那么我希望你这样做。在某些情况下,如果只有3个,可能会出现错误操作。

以下是NOP的问题:

操作

NOP不执行任何操作,也不能保证耗时。 处理器可能会在它到达目标之前将其从管道中删除 执行阶段

使用NOP填充,例如放置后续指令 在64位边界上


其他手臂皮质设备的文档中也有同样的信息,因此将该指令用于填充以外的任何目的都是不可靠的。您唯一能保证的是,此指令将占用2个nop或4个字节nop.w,并且它不会执行任何操作-仅此而已。

以下是nop的问题:

操作

NOP不执行任何操作,也不能保证耗时。 处理器可能会在它到达目标之前将其从管道中删除 执行阶段

使用NOP填充,例如放置后续指令 在64位边界上


其他手臂皮质设备的文档中也有同样的信息,因此将该指令用于填充以外的任何目的都是不可靠的。您唯一能保证的是,此指令将占用2个nop或4个字节nop.w,并且它不会执行任何操作-仅此而已。

3个nop不保证消耗3个周期。当然,在某些情况下,它们会在Cortex-M3上消耗2个周期——在这些情况下,您可能需要使用3个以上的NOP才能获得所需的效果

“有趣”的场景很可能不会出现在公共代码中,或者还需要其他事件的特定计时,因此您可能不太可能观察到它们。关键的一点是没有保证,这种故障的可观测性通常很低


即使您在某个地方只是错误地使用了2个NOP,您的代码也可能在大部分时间都能正常工作,直到其他地方的更改可能会影响对齐并暴露出故障。

3个NOP不能保证消耗3个周期。当然,在某些情况下,它们会在Cortex-M3上消耗2个周期——在这些情况下,您可能需要使用3个以上的NOP才能获得所需的效果

“有趣”的场景很可能不会出现在公共代码中,或者还需要其他事件的特定计时,因此您可能不太可能观察到它们。关键的一点是没有保证,这种故障的可观测性通常很低


即使您在某个地方只是错误地使用了2个NOP,您的代码也可能在大部分时间都正常工作,直到其他地方的更改可能会影响对齐并暴露出故障。

ISB指令是4个周期的原因非常简单。Cortex-M指令集是16位和32位指令的混合体。Cortex-M设计中支持六条32位指令,例如Cortex-M0:BL、MSR、MRS、ISB、DMB、DSB

所有这六条指令都可以混合在16位指令中

问题是处理器如何知道哪条指令是16- 位和哪个是32位?为了回答这个问题,处理器读取前16位并解码1个周期。如果操作码与32位指令匹配,则它知道下一条16位指令实际上是32位指令的后半部分,并尝试执行它3个周期

这使得Cortex-M内核中的所有32位指令都是1+3个周期=4个周期


要刷新管道,如果确定核心实现,可以使用3个NOP。您必须确保核心没有分支预测和动态指令优化,这会删除连续的NOP。如果您确定缺少此功能,则使用3条NOP指令,您将节省1个周期。但如果您不使用ARM,并且希望ARM代码能够移植到其他架构(如ARMv7等),则必须使用ISB指令,这是一条32位指令,需要4个周期

ISB指令是4个周期的原因很简单。Cortex-M指令集是16位和32位指令的混合体。Cortex-M设计中支持六条32位指令,例如Cortex-M0:BL、MSR、MRS、ISB、DMB、DSB

所有这六条指令都可以混合在16位指令中

问题是处理器如何知道哪条指令是16位的,哪条是32位的?为了回答这个问题,处理器读取前16位并解码1个周期。如果操作码与32位指令匹配,则它知道下一条16位指令实际上是32位指令的后半部分,并尝试执行它3个周期

这使得Cortex-M内核中的所有32位指令都是1+3个周期=4个周期


要刷新管道,如果确定核心实现,可以使用3个NOP。您必须确保核心没有分支预测和动态指令优化,这会删除连续的NOP。如果您确定缺少此功能,则使用3条NOP指令,您将节省1个周期。但如果您不使用ARM,并且希望ARM代码能够移植到其他架构(如ARMv7等),则必须使用ISB指令,这是一条32位指令,需要4个周期

也许是为了优化尺寸?我不相信它对皮层M0有任何真正的影响,一个nop可能就足以作为一个中断屏障。与处理器系列其他成员的点兼容性,不需要依赖于细微的体系结构细节,这些细节在判断错误时可能会产生特别细微的bug。我想,如果以前的外设存储需要额外的周期来传播和发出中断,那么额外的周期可能会很有用。你无法预测将来的内核是什么样子,现在3个NOP可能在一个/一些内核上工作,但可能并不总是这样。如果指令的任务是执行此功能,只要该指令得到支持,这就是明智的解决方案。我不需要预测。我知道它现在是如何工作的,这才是最重要的。经过一些研究,我发现没有人真正知道答案。我想我会继续使用3个NOP,并保存一个循环。@old_timer我通常会删除cortex-m3标签,因为大多数Q/A不仅仅针对m3,而是适用于m3/M4和其他cortex-M内核。然而,我看到你添加了很多,我不想和你“打架”。请参阅:,其中才华横溢的meta-people以离题结束。每个问题都应该有这两个标签吗?我试着做单独的标签,但有人想把它们都集中到cortex-m3标签中,所以我只是遵循这一点。也许是为了优化尺寸?我不相信它对皮层M0有任何真正的影响,一个nop可能就足以作为一个中断屏障。与处理器系列其他成员的点兼容性,不需要依赖于细微的体系结构细节,这些细节在判断错误时可能会产生特别细微的bug。我想,如果以前的外设存储需要额外的周期来传播和发出中断,那么额外的周期可能会很有用。你无法预测将来的内核是什么样子,现在3个NOP可能在一个/一些内核上工作,但可能并不总是这样。如果指令的任务是执行此功能,只要该指令得到支持,这就是明智的解决方案。我不需要预测。我知道它现在是如何工作的,这才是最重要的。经过一些研究,我发现没有人真正知道答案。我想我会继续使用3个NOP,并保存一个循环。@old_timer我通常会删除cortex-m3标签,因为大多数Q/A不仅仅针对m3,而是适用于m3/M4和其他cortex-M内核。然而,我看到你添加了很多,我不想和你“打架”。请参阅:,其中才华横溢的meta-people以离题结束。每个问题都应该有这两个标签吗?我试着做单独的标签,但有人想把它们都集中到cortex-m3标签中,所以我只是遵循这一点。