具有多核处理器的关键部分

时间:2009-06-11 11:12:34

标签: multithreading synchronization cpu-architecture

使用单核处理器,所有线程都从一个CPU运行,在内存中使用某些互斥(或信号量等)上的原子测试和设置操作实现关键部分的想法似乎直截了当;因为你的处理器正在程序中的一个位置执行测试和设置,所以它一定不能从程序中的另一个位置做伪装成其他线程。

但是当你真的拥有多个物理处理器时会发生什么?似乎简单的指令级原子性是不够的,b / c有两个处理器可能同时执行它们的测试和设置操作,你真正需要保持原子性是访问共享内存位置的互斥。 (如果共享内存位置被加载到缓存中,那么整个缓存一致性也要处理...)

这似乎会比单核案件产生更多的开销,所以问题的关键在于:它有多糟糕?更糟糕吗?我们只是忍受它吗?或者通过强制执行一个策略来回避它,即进程组中的所有线程都必须存在于同一个物理核心上?

6 个答案:

答案 0 :(得分:16)

多核/ SMP系统不只是几个CPU粘在一起。对并行做事有明确的支持。所有同步原语都是在atomic CAS行的硬件帮助下实现的。该指令锁定CPU和内存控制器(以及执行DMA的设备)共享的总线并更新内存,或者仅更新依赖cache snooping的内存。这反过来导致cache coherency算法强制所有相关方刷新他们的缓存。

免责声明 - 这是非常基本的描述,这里有更多有趣的东西,如虚拟和物理缓存,缓存回写策略,内存模型,围栏等。

如果您想了解更多有关操作系统如何使用这些硬件设施的信息,请点击这里an excellent book

答案 1 :(得分:6)

多核cpu的供应商必须注意不同的核在执行保证原子内存访问的指令时协调自己。

例如,在intel芯片上你有'cmpxchg'指令。它将存储在存储器位置的值与预期值进行比较,如果两者匹配则将其交换为新值。如果在它前面加上'lock'指令,则保证它对所有内核都是原子的。

答案 2 :(得分:3)

您需要一个测试和设置,强制处理器通知操作的所有其他核心,以便他们知道。是的,这会带来开销,你必须忍受它。设计多线程应用程序的原因是它们不会经常等待同步原语。

答案 3 :(得分:3)

  

或者通过强制执行一个策略来回避它,即进程组中的所有线程都必须位于同一个物理核心上?

这将取消多线程的全部要点。当您使用锁定,信号量或其他同步技术时,无论您使用多少核心,您都依赖操作系统来确保这些操作是互锁的。

锁定释放后切换到其他线程的时间主要取决于上下文切换的成本。 This SO线程处理上下文切换开销,因此您可能需要检查它。

还有一些其他有趣的主题:

您还应该阅读此MSDN文章:Understanding the Impact of Low-Lock Techniques in Multithreaded Apps

答案 4 :(得分:1)

存储器访问由存储器控制器处理,存储器控制器应该处理多核问题,即它不应允许同时访问相同的地址(可能通过存储器页或存储器线来处理)。因此,您可以使用一个标志来指示另一个处理器是否正在更新某个块的内存内容(这是为了避免一种脏读类型,其中部分记录已更新,但不是全部)。

更优雅的解决方案是,如果处理器具有此功能,则使用HW信号量块。 HW信号量是一个简单的队列,其大小可以是no_of_cores -1。这就是TI的6487/8处理器。您可以直接查询信号量(并循环直到它被释放)或进行间接查询,一旦核心获取资源,这将导致中断。请求按排序顺序排列并按服务顺序提供。信号量查询是原子操作。

缓存一致性是另一个问题,在某些情况下您可能需要执行缓存写回和刷新。但这是一个非常缓存实现的具体事情。有了6487/8,我们需要在一些操作上做到这一点。

答案 5 :(得分:0)

那么,根据您在家里铺设的计算机类型,请执行以下操作:编写一个简单的多线程应用程序。在单核(Pentium 4或Core Solo)上运行此应用程序,然后在多核处理器(Core 2 Duo或类似处理器)上运行它,看看速度有多大。

当然这些是不公平的比较,因为Pentium 4和Core Solo的速度要比Core 2 Duo慢很多。也许比较Core 2 Duo和Core 2 Quad与可以使用4个或更多线程的应用程序。

您筹集了许多有效积分。 Muliple处理器引入了很多头痛和开销。但是,我们只需要和它们一起生活,因为如果关键部分足够长,并行性的速度提升可能远大于它们。

关于将所有线程放在同一物理内核上的最终建议,这完全违背了多核计算机的要点!