我正在努力更好地了解多核处理器的工作方式以及我作为程序员如何利用它们。
假设我有一个标准的.net控制台应用。它不做任何多线程。它只运行在其中一个核心上吗?如果是这样的话,它会运行哪个核心并且每次都是同一个核心?
现在让我们说我有另一个控制台应用程序在内部旋转了一堆线程。线程是否在可用内核之间划分,或者它们都在初始线程所在的同一核心上运行,我必须做一些特殊的事情才能使用其他可用的内核?
答案 0 :(得分:11)
核心,线程,进程和类之间的关系可能很复杂。当你开始考虑你可能没有编写的代码(例如.NET框架本身)时跑。
简单的答案是,除非您专门编写控制台应用程序以使用多个线程,否则它将在单个核心上运行。
现在,有一些.NET框架类在幕后可能会使用多个线程,在这种情况下,您的进程可能会使用多个核心。很多BCL都不使用线程,但像WCF和WF这样的框架可以在内部使用线程。
此外,运行时环境可能会使用多个线程(在某些情况下)进行垃圾回收等操作。除此之外,运行时环境可能会将您的代码从核心移动到核心。发生这种情况是因为操作系统本身使用先发制人的多任务处理来调度线程 - 因此不保证单个线程与特定核心具有亲缘关系。
对于问题的第二部分,如果进程明确生成线程,它们通常(但不总是)最终会在不同的核心上运行。大多数情况下,这些线程将被安排在任何具有容量的核心上运行 - 而线程(如前所述)可能会从核心移动到核心。您不必做任何特殊的操作(通常)以获得多个内核来运行您的代码。
实际上,有时候难以实现的是逆:确保特定线程仅在单个核上运行。这被称为affinity。在某些情况下,希望将线程关联到特定核心以改善参考的局部性并最小化高速缓存未命中的可能性。但是,大多数情况下,您不必担心这一点。
如果您有兴趣了解有关Windows上并发编程的更多信息(以及在.NET中),我建议您选择Joe Duffy Concurrent Programming on Windows的副本。
答案 1 :(得分:5)
大多数操作系统使用preemptive multitasking来安排应用程序的运行。
它只在1个内核上运行吗?如果是这样的话,它会运行哪个核心并且每次都是同一个核心?
不,不。操作系统可以在中途自由停止进程,并将其移至不同的核心。这经常发生。但是,如果它是单线程的,那么您的应用程序代码一次只能在一个核心上运行。 (在.NET中,进程总是使用额外的线程来处理诸如垃圾收集之类的事情,而BCL通常会在内部使用线程。)
现在让我们说我有另一个控制台应用程序在内部旋转了一堆线程。线程是否在可用核心之间划分
理想情况下,是的。在实践中,操作系统通常会使用一些资源,并且线程可能会在核心之间移动等等。
或所有这些都在初始线程所在的同一核心上运行,我必须做一些特别的事情才能使用其他可用的核心?
没有。大多数情况下,线程被推送到其他核心,特别是如果它们处于空闲状态。但这取决于操作系统。
话虽这么说,某些操作系统允许您为特定线程指定processor affinity,这允许您将线程放置到特定处理器上并将其保留在那里。大多数操作系统仅将此视为建议(并且仍将移动它们),但许多嵌入式系统将完全遵守请求。