2010-05-25 131 views
2

如果我的机器上有X个内核,并且启动X个线程。让我们假设为了争论,每个线程在它使用的内存,硬盘等方面是完全分离的。操作系统会知道将每个线程发送到一个核心,或者在多个线程的一个核心上进行更多时间切片。 问题归结为,如果我有X核心,并且我的程序必须执行独立计算,我应该启动X个线程,每个线程是否都通过管道连接到核心,或者是因为我有X个核心可以启动X线程完全错误?我在想。 这是用C# -线程和内核

+1

Duplicate:http://stackoverflow.com/questions/32343/how-do-i-spawn-threads-on-different-cpu-cores。 而且,通过在自己的内核上运行每个线程,您不一定会获得更好的性能,因为您不知道其他内核正在做什么(操作系统知道)。 – Seth 2010-05-25 20:01:43

+0

我认为这个想法是为每一个可以独立运行的业务创建一个线程。计算机如何以及为何决定运行线程的核心取决于各种事情,我建议您不要试图微观管理。 – overslacked 2010-05-25 20:03:29

回答

2

我会说没有...

的.NET团队推出了TPL明确委托线程执行利用多个内核。 Windows Vista没有太多内置的智能来支持将线程委托给多个内核的操作系统。考虑到Windows 7对多核心的支持得到了很大的改善,我不惊奇地发现.NET框架(4.0)中的这种改进。

0

我想这可能取决于平台和操作系统。根据我的经验,在Linux上使用C++控制台应用程序时,如果需要从机器中尽可能多地获得性能,则在X内核上使用X线程是正确的。但是请注意,任何并发任务(包括GUI)都会占用您的程序可用的CPU时间。但是在没有GUI的专用服务器上,我的每个内核都使用99-100%的专用程序。

0

由于C#使用本机线程,我觉得我可以评论,即使我的经验主要是Java(在Windows上)。一般来说,操作系统会尝试平衡负载,所以如果你在一个线程上最大化了一个计算密集型任务的核心,那么就会在该核心上安排很少的线程。

我最近编写了一些使用任务框架的cpu密集型多线程代码,其中工作分解为小任务并馈送到N个队列。每个队列都由一个线程拥有。由于我从1..X增加了线程数,其中X是核心数,所以线速度提高了。

所以一般来说,答案是肯定的,你可以期待操作系统做正确的事情,特别是随着线程数量的增加和接近核心数量的增加。

2

这完全取决于每个线程要做多少工作。如果您要在4核机器上启动4个线程,并且只是运行一个紧密循环,那么它很可能会占用CPU总时间的100%。

论是否更广泛的问题,给出ķ线程和ķ内核,操作系统将自动安排每个线程0->ķ -1在芯0->ķ -1,则这不能得到保证。一般来说,一旦某个线程即将安排运行,它将被分配给下一个可用的CPU。但是,我相信,操作系统将是智能的,并且会尝试重用先前线程所运行的相同内核,因为线程本地数据可能会缓存在该内核上。然而,这就是说,在当今共享处理器缓存的世界中,这不会是良好线程调度的先决条件。

通过调用SetProcessorAffinity()方法,可以影响给定内核的线程亲和力。不过,我倾向于避免这样做,因为操作系统通常很擅长让你的线程正确。

注意

有跨越多个线程非一致内存访问,这将导致线程阻塞对方即使没有参与锁定一些有趣的问题。

假设您有大量的值,并且您希望n线程对它们进行操作。您必须确保每个线程都访问单独缓存行上的数据,以访问其他线程访问的数据 - 这是一个低级问题,并不是.Net程序员(但是那些在C++或更低级别平台上长大的人)所使用的问题来处理。

该问题在MSDN杂志的this article中得到了很好的展示。它使迷人的阅读。

0

通常由操作系统调度程序将任务分配给正在执行的内核。 设N是要运行的任务的数量,X是执行内核的数量。

如果N < X除非您有其他任务正在运行,否则您的机器资源将无法完全使用。 如果N> = X,它是OS对所有可用内核之间的线程进行负载平衡的“最佳意图”。 实际上,您不能保证所有任务都将在单独的核心上运行,除非您在每个任务线程上强制执行关联。 事实上,如果您的旧操作系统不理解SMT处理器,它将会被愚弄,并且可以为每个单核分配多个任务,而其他内核可能会空闲。