2010-09-28 96 views
7

我试图更好地理解多核处理器是如何工作的,以及作为一名程序员如何利用它们。应用程序如何在多核机器上运行?

比方说,我有一个标准的.net控制台应用程序。它不会执行任何多线程。它只能在1个内核上运行吗?如果是的话,哪个核心运行,每次都是一样的?

现在我们假设我有另一个控制台应用程序在内部激活一堆线程。线程是否在可用的内核之间被分开,或者所有的线程都在最初的线程所在的同一个内核上运行,我必须做一些特殊的事情才能使用其他可用的内核?

回答

5

大多数操作系统使用preemptive multitasking来安排应用程序运行。

它只能在1个内核上运行吗?如果是的话,哪个核心运行,每次都是一样的?

不,没有。操作系统可以自由停止进程,并将其移至不同的核心。这经常发生。但是,如果它是单线程的,那么您的应用程序代码将一次只能在单核上运行。 (在.NET中,过程总是使用额外的线程的东西,如垃圾收集,而BCL会经常使用内部线程)。

现在让我们假设我有一个内部旋转了一堆线程的另一个控制台应用程序。线程是否在可用核心之间被分开

理想情况下,是的。在实践中,操作系统通常会使用一些资源,而线程可能会内核之间搬来搬去,等

或全部它们在同一个核心的初始线程是所有跑,我要做一些特别的事情来使用其他可用的东西?

不是。大多数情况下,线程都被推送到其他内核上,特别是在它们闲置时。然而,这取决于操作系统。

也就是说,有些操作系统允许您为特定的线程指定processor affinity,这允许您将线程放置到特定的处理器并留在那里。大多数操作系统只会将此视为一种建议(并且仍会移动它们),但是许多嵌入式系统将完全满足这些要求。

+0

+1。此外,根据.NET框架的版本,垃圾收集可能发生在单独的线程上。此外,.NET BCL中还存在一些方法,如果需要,它可以在内部使用多个线程来执行。具体来说,我们想到了WCF和WF框架。如果这些API消耗完了,那么最终可能不仅仅使用单个线程。 – LBushkin 2010-09-28 21:13:01

+0

@LBushkin:非常真实。我将其添加到我的答案中。 – 2010-09-28 21:13:38

11

核心,线程,进程和类之间的关系可能很复杂。更何况,当你开始考虑如何编写代码时(例如,.NET框架本身)计划运行。

简单的回答是,除非你编写你的控制台应用程序使用多个线程,否则它将运行在单个内核上。

现在,有一些.NET框架类在后台可能会使用多个线程,在这种情况下,您的进程可能会利用多个内核。许多BCL不使用线程,但框架如WCFWF可能在内部使用线程。

此外,运行时环境可能会使用多个线程(在某些情况下)进行垃圾回收等操作。除此之外,运行时环境可能会将代码从核心转移到核心。发生这种情况是因为操作系统本身使用先占式多任务来调度线程 - 所以单个线程并不保证与特定内核有亲和力。

对于问题的第二部分,如果某个进程明确产生了线程,它们通常(但不总是)最终会在单独的核心上运行。大多数情况下,这些线程将被安排在任何具有容量的内核上运行 - 并且线程(如前所述)可能会从核心转移到核心。你不应该做任何特殊的事情(通常)来让多个核心运行你的代码。

实际上,它有时难以实现:确保特定线程只能在单个核心上运行。这被称为affinity。在某些情况下,需要将线程关联到特定核心以改善参考的局部性,并最大限度地减少缓存未命中的可能性。然而,大多数情况下,您不需要担心这一点。

如果您有兴趣了解更多关于Windows(和.NET)的并发编程的知识,我建议您拿起Joe Duffy的Concurrent Programming on Windows的副本。

+0

关于GC的好处;).NET应用程序总是使用多线程,因为这... – 2010-09-28 21:11:36

+1

这个答案不仅适用于.NET应用程序;其他系统会显示类似的行为,特别是在使用大型框架或库时。 – Karmastan 2010-09-28 21:34:06

+0

有什么办法可以请求多线程应用程序不同时使用多个内核,以确保线程之间的内存一致性? – supercat 2010-09-28 22:20:19