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

什么是处理器 Lock# 信号及其工作原理?

如何解决什么是处理器 Lock# 信号及其工作原理?

我正在读一本关于汇编(中级)的书,它提到一些像 xchg 这样的指令会自动断言处理器 LOCK# 信号。在网上搜索它发现它赋予处理器任何共享内存的专有权,但没有具体细节。这让我想知道这个权利是如何运作的。

  1. 这是否意味着任何其他计算机设备(例如 GPU 或其他设备)无法访问内存。实际上,其他设备可以直接与 RAM 通信,而无需先通过 cpu
  2. 处理器如何知道它处于这种锁定状态,例如它是否保存在控制或 rflags 寄存器中,或者因为我无法看到在具有多核 cpu 时此操作是如何工作的。
  3. 我访问的网站说锁定任何共享内存。这是否意味着在此锁定期间,整个 RAM 被锁定,或者只是执行指令的内存页(或部分内存而不是全部)被锁定。

解决方法

基本问题是一些指令读内存,修改读的值,然后写一个新的值;如果在读取和写入之间内存的内容发生变化,(某些)并行代码最终可能会处于不一致的状态。

一个很好的例子是一个 CPU 执行 inc dword [foo] 而另一个 CPU 执行 dec dword [foo]。两条指令(在两个 CPU 上)执行后,值应该和原来的一样;但是两个 CPU 都可以读取旧值,然后两个 CPU 都可以修改它,然后两个 CPU 都可以写入它们的新值;导致该值比您预期的高 1 或低 1。

解决方案是使用 #lock 信号来防止其他任何东西同时访问同一块内存。例如。第一个 CPU 会断言 #lock,然后执行读取/修改/写入,然后取消断言 #lock;其他任何事情都会看到 #lock 被断言,并且必须等到 #lock 被取消断言才能进行任何内存访问。换句话说,这是一种简单的互斥形式(类似于自旋锁,但在硬件中)。

当然“其他一切都必须等待”有性能成本;所以它主要只在软件明确请求时完成(例如 lock inc dword [foo] 而不是 inc dword [foo]),但也有一些隐式完成的情况 - xchg 指令,当操作数使用内存并更新时CPU 使用的某些表中的脏/访问/忙标志(用于分页和 GDT/LDT/IDT 条目)。还;后来(我认为是 Pentium Pro?),该行为被优化为与缓存一致性协议一起使用,因此如果可以将缓存行置于独占状态,则不会断言 #lock

注意:过去有 2 个 CPU 错误(Intel Pentium "0xF00F" 错误和 Cyrix "Coma" 错误),其中 CPU 可以被欺骗以断言 #lock 信号并且永远不会取消断言它;导致整个系统锁定,因为没有任何东西可以访问任何内存。

  1. 这是否意味着任何其他计算机设备(例如 GPU 或其他设备)无法访问内存。实际上,其他设备可以直接与 RAM 通信,而无需先通过 CPU。

是的。如果 #lock 被断言(不包括较新的 CPU 可以将缓存行置于独占状态的情况);任何访问内存的操作都必须等待 #lock 被取消断言。

注意:大多数现代设备都可以/确实可以直接访问内存(在不使用 CPU 传输数据的情况下向/从 RAM 传输数据)。

  1. 处理器如何知道它处于这种锁定状态,例如它是否保存在控制或 rflags 寄存器中,或者因为我无法看到在具有多核 CPU 时此操作是如何工作的。

它不保存在任何寄存器的内容中。它实际上是总线或链路上的电子信号。对于一个极其简单的例子;假设总线有 32 条“地址”线、32 条“数据”线和一条 #lock 线;其中“断言 #lock”表示该 #lock 线上的电压从 0 伏升至 3.3 伏。当任何东西想要读取或写入内存时(在尝试更改“地址”线或“数据”线上的电压之前),它会检查 #lock 线上的电压是否为 0 伏。

注意:真正的总线要复杂得多,还需要一些其他信号(例如,传输方向、避免冲突、“I/O 端口或物理内存”等);现代总线使用串行通道而不是并行线路;现代系统使用“点对点链接”而不是“所有事物共享的公共总线”。

  1. 我访问的网站说锁定任何共享内存。这是否意味着在此锁定期间,整个 RAM 被锁定,或者只是执行指令的内存页(或部分内存而不是全部)被锁定。

最好说公交车上锁了;一切都必须使用总线来访问内存(并且当总线被锁定时,没有其他任何东西可以使用总线,即使其他东西试图将总线用于与内存无关的事情 - 例如发送 IRQ 到一个 CPU)。

当然(由于积极的性能优化 - 主要是“如果可以将缓存行置于独占状态”优化)最好说硬件可以做任何事情,只要结果表现良好好像有一个共享总线被锁定(即使没有共享总线并且实际上没有任何东西被锁定)。

注意:80x86 支持未对齐访问(例如,您可以lock inc dword [address] 访问可以跨越边界的地方),如果内存访问确实跨越边界,则 CPU 需要组合 2 个或多个部分(例如距一个缓存行的末尾几个字节和距下一个缓存行开头的几个字节)。现代虚拟内存意味着,如果虚拟地址跨越页面边界,CPU 需要访问 2 个不同的虚拟页面,这些页面可能具有“非常不相关”的物理地址。如果理论上的 CPU 试图实现独立的锁(每个内存区域不同的锁),那么它也需要支持断言多个锁信号。这可能会导致死锁 - 例如一个 CPU 锁定“内存页面 1”,然后尝试锁定“内存页面 2”(并且不能,因为它已被锁定);而另一个 CPU 锁定“内存页面 2”,然后尝试锁定“内存页面 1”(并且不能,因为它已被锁定)。为了解决理论上的 CPU 必须使用“全局锁排序”的问题 - 始终以特定顺序断言锁。最终结果将是大量的复杂性(在这种情况下,增加的复杂性可能比节省的性能成本更高)。

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