【问题标题】:Synchronization in multiprocessor systems多处理器系统中的同步
【发布时间】:2018-01-19 02:39:25
【问题描述】:

我了解在单核处理器中使用 信号量 可以轻松完成同步。但是在多核的情况下,如果多个进程想在同一时刻进入临界区,是全部进入临界区还是只有一个获胜?获胜者过程获胜的标准是什么?

【问题讨论】:

    标签: process parallel-processing x86 operating-system


    【解决方案1】:

    当两个内核尝试同时进入临界区时,它们都尝试同时写入内存中的信号量,使用锁定的读-修改-写操作。为了让内核完成写入,缓存必须获得对包含信号量的缓存行的独占访问权限。这会强制另一个核心将该行标记为无效。缓存协议确保只有一个内核可以获得独占访问,并且该内核进入临界区。

    同时,另一个也在尝试写入信号量的内核必须等待,因为它仍然需要独占访问高速缓存行。一旦第一个核心完成其写入操作,另一个核心将获得独占访问权限并可以完成其读取-修改-写入。但是 read-modify-write 的结果告诉它信号量很忙,所以它不能进入​​临界区,直到它检测到信号量​​已经被释放。

    【讨论】:

      【解决方案2】:

      即使存在多个内核,信号量(或互斥体,或大多数其他同步原语)的工作方式也一样 - 只有指定数量的线程可以进入信号量。如果它只在单处理器机器上工作,它确实是一个糟糕的信号量!

      要完成这项工作需要多种机制,我将尝试给出一个高层次的观点。

      请注意,内存仍然在不同的内核之间共享。 CMPXCHG instruction 是了解如何使用共享内存同步内核的一种简化但 IMO 有用的方法。该指令可以原子地(请参阅下面的更多详细信息)比较和设置内存地址。如果内存地址具有您要比较的值,它还将零标志设置为 1。

      考虑以下代码:

      wait:
      mov eax, 0
      mov ecx, 1
      lock cmpxchg [address of lock], ecx
      jne wait
      // We now own the lock
      

      代码在逻辑上循环执行以下操作:仅当 lock 为 0 时才将 lock 的值设置为 1。

      这段代码可以多核运行,cmpxchg的原子性保证只有一个核获胜。

      如果每个核心都有自己的缓存(现在通常是这种情况),情况会变得更加复杂。对于单独的缓存,每个内核都有自己的内存视图,因此必须注意确保这些内存视图是一致的。简短的回答是,这可以通过让缓存在数据更改时相互通知来完成,以便其他缓存可以在需要时使它们的副本无效或更新。查阅窥探和 MESI 协议以了解更多详细信息。

      请注意,如果内核在同一个物理芯片上,那么它们都在竞争内存总线,并且内核之间有共享它的机制(例如仲裁机制;另请参阅LOCK 指令)。

      【讨论】:

        【解决方案3】:

        信号量只是在一个系统中通过线程进行信号化的一种方式。您可以在不影响其使用的单核或多核 CPU 中使用信号量。

        现在让我们回到您的问题。如果您有关键部分并且多个线程想要进入该区域,它们将全部进入该区域。您需要了解主线程(例如)或将启动它们的其他线程,在它们之间产生一些时间间隔(大约几个 ns 的时间空间非常小)。 这就是我们使用 signalisation 的原因,因为我们不想要“赢家”,另一方面,在几乎所有情况下,线程都可能在该关键部分进行不必要的更改。

        在单核系统中,您只能实现仅并发的进程调度(假并行,通过 TaskScheduler ),因为不同的线程必须通过分配的时隙共享核心。

        【讨论】:

        • 感谢您的回答。其实我说的是 Process 而不是 thread 。所以对于几个不同的进程,它们是相互独立的,我们不能像你所说的那样在这些进程之间产生微小的时间差异。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-01-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-03
        • 2014-08-17
        • 2012-08-19
        相关资源
        最近更新 更多