微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

程序计数器、栅栏和处理器重新排序

如何解决程序计数器、栅栏和处理器重新排序

我知道除了编译器之外,处理器还可以对指令进行重新排序。

我有几个问题想不通。

假设我们有三个指令:

节目顺序

S1 S2 S3

经过处理器重新排序后,顺序变为(无论出于何种原因):

S3 S2 S1

  • 那么当处理器执行 S1(按程序顺序)时,程序计数器的值是多少?
  • 如果 Windows(或其他操作系统),上下文将线程切换出并在另一个处理器中调度它,另一个处理器如何知道接下来要执行哪条指令? (是否保证进行相同的重新排序?)
  • 在另一个线程上调度线程后,一个处理器上的内存栅栏(例如,由原子比较和交换指令创建的完整栅栏)是否有效?

对此的任何想法都非常感谢。

解决方法

  1. 每条指令都有一个指令指针。

  2. 虽然指令可能会乱序执行,但它们总是按顺序完成。当发生中断或故障时,保存的IP地址之前的所有指令都已完成。任何后续指令的结果都将被丢弃。当执行恢复时,它从保存的地址开始。

  3. 操作系统在另一个处理器上调度线程所采取的步骤包括在两个处理器上的防护操作,因此当线程在新处理器上恢复时,所有先前的操作都被完全防护(无论是否存在任何显式防护)在线程的代码中)。

,

与静态编译时排序不同,乱序 exec 保留了按程序顺序运行指令的错觉。包括中断处理程序看到的情况。当前的 CPU 不会重命名特权级别,因此它们通常会回滚到一致状态作为处理异常或中断的一部分,而不是保持未执行的指令在运行中。 When an interrupt occurs,what happens to instructions in the pipeline?


这也意味着中断严格指令之间传递,而不是在一个指令的中间。 Interrupting an assembly instruction while it is operating(除了像 rep movsb 这样的“可中断”指令在逻辑上作为多条指令工作,或者 vpgatherdd 已经记录了一个收集操作数中页面错误的语义。)

其他内核观察到的内存排序是另一回事,即使在有序 CPU 上也可能与程序顺序不同。 (Can a speculatively executed CPU branch contain opcodes that access RAM?)

用于上下文切换的内核代码需要包含足够强大的屏障,以便线程在另一个内核上恢复时以程序顺序查看自己的存储。通常只需释放/获取同步就足够了(并且您已经需要其他内核上的内核类似的东西来恢复寄存器值)。或许还有一个 sfence 可以使其适用于 x86 上的 NT 存储。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。