如果我的机器上有X核心,我就会启动X线程。让我们假设为了论证,每个线程在它使用的内存,硬盘等方面完全分开。操作系统是否会知道将每个线程发送到核心,或者在多个线程的一个核心上进行更多时间切片。 问题归结为,如果我有X核并且我的程序必须进行独立计算,我应该启动X线程,它们每个都会通过管道传输到核心,或者假设因为我有X核心我可以启动X线程完全错了?我在想它。 这是用C# -
答案 0 :(得分:2)
我要说不......
.NET团队引入了TPL来显式委派线程执行以利用多个核心。 Windows Vista没有内置太多智能来支持将线程委派给多个内核的操作系统。考虑到Windows 7对多核的支持得到了很大改进,我对.NET框架(4.0)的改进并不感到惊讶。
答案 1 :(得分:2)
这完全取决于每个线程要做多少工作。如果您要在4核计算机上启动4个线程并且只是运行紧密循环,那么它很可能会消耗100%的总CPU时间。
在更广泛的问题上,给定 k 线程和 k 核心,操作系统是否会自动安排每个线程0-> k 核心0-> k -1上的-1,则无法保证这一点。通常,一旦线程即将被安排运行,它将被分配给下一个可用的CPU。但是,我相信操作系统将是智能的,并且会尝试重用先前运行的线程所使用的相同内核,因为线程本地数据可能会缓存在该内核上。但是,在今天的共享处理器缓存世界中,这不是良好的线程调度的先决条件。
您可以通过调用SetProcessorAffinity()方法来影响线程对给定核心的亲和力。但是,我倾向于回避这样做,因为操作系统通常非常善于让你的线程正确。
<强>注意强>
跨多个线程的非统一内存访问存在一些有趣的问题,即使没有涉及锁定,也会导致线程相互阻塞。
假设您拥有大量值,并且希望 n 线程对它们进行操作。您必须确保每个线程访问单独高速缓存行上的数据到其他线程访问的数据 - 这是一个低级问题,不是.Net程序员(但是那些在C ++或低级别平台上长大的人)处理。
问题在MSDN杂志的this article中得到了很好的证明。它令人着迷。
答案 2 :(得分:0)
我想这可能取决于平台和操作系统。根据我的经验,在Linux上使用C ++控制台应用程序,如果您需要从机器中尽可能多地挤出性能,那么在X核上使用X线程是正确的。但请注意,任何并发任务(包括GUI)都会耗尽程序可用的CPU时间。但是在没有GUI的专用服务器上,我的每个核心99-100%仅由我的程序使用。
答案 3 :(得分:0)
由于C#使用本机线程,我觉得我可以发表评论,尽管我的经验主要是使用Java(在Windows上)。一般情况下,操作系统会尝试平衡负载,因此如果您在一个线程上使用计算密集型任务最大化核心,那么将在该核心上安排几个线程。
我最近使用任务框架编写了一些cpu密集型多线程代码,其中工作分为小任务并提供给N个队列。每个队列都由一个线程拥有。因为我增加了1..X的线程数,其中X是核心数,所以线性加速了。
所以一般来说,答案是肯定的,你可以期望操作系统做正确的事情,特别是当线程数增加并接近核心数时。
答案 4 :(得分:0)
通常由OS调度程序将任务分配给执行的核心。 设N是要运行的任务的数量,X是执行核心的数量。
如果N < X除非您正在运行其他任务,否则您的计算机资源将无法充分使用。 如果N> = X,那么操作系统的“最佳意图”是在所有可用内核之间对线程进行负载均衡。 实际上,除非在每个任务线程上强制执行关联,否则无法保证所有任务都将在不同的核上运行。 事实上,如果您的旧操作系统不了解SMT处理器,它将被愚弄,并且可以为每个核心分配多个任务,而其他核心可能处于空闲状态。