多核用法,线程,线程池

时间:2008-12-28 12:36:53

标签: .net multithreading multicore

我对多线程编程和多核使用有一些疑问。

特别是我想知道操作系统和/或框架(这是.NET)如何处理大量使用的核心。

这是关于线程的问题:

  • 当生成新线程时,将线程分配给特定核心的算法是什么?
    1. 循环算法类型
    2. 随机
    3. 目前使用最少的核心
  • 如果不是当前使用最少的核心,那么确定这种类型的代码是否会使线程的典型使用相形见绌,从而使事情变得更糟?
  • 线程是否在其生命周期内从一个核心移动到另一个核心?如果是这样,这是否会处理由于某种原因“过度使用”的内核,因此操作系统会尝试将线程混洗到较少使用的内核以帮助系统?如果不是,为什么不呢?

我的最后一个问题,基本上是上面的重用,是关于.NET ThreadPool类,它处理诸如.BeginInvoke之类的东西。这堂课有没有做过这些?如果不是,为什么不,或者应该呢?

有没有办法调整这个处理,在操作系统上提示这个特定的线程,当你指定一个核心时请多关注它,因为我知道它会使用很多cpu。那会有意义吗?或者“很多cpu”只是相对的,因此不够好?

2 个答案:

答案 0 :(得分:18)

  

当产生新线程时,是什么   分配线程的算法   到一个特定的核心?

这完全取决于操作系统。答案通常是经过大量修改的循环方案。每隔x毫秒,一个核心被中断,并且一个新的线程放在它上面(所以没有“最少使用的核心”。只要有线程准备好运行,每个核心都有事情要做。)

在Windows中,我认为最高优先级的线程/进程总是被选中执行。 (因此,如果在单核系统上有一个进程以高优先级运行,那么该进程可能会100%运行,从而使每个其他进程无法运行。当然,这仅适用于该进程从不阻塞的情况,这在现实世界。

当然,因为像Windows这样的现代操作系统很复杂,所以它还有很多。某些流程会不时给予优惠待遇,但根据经验,Windows将始终选择高优先级流程(这就是为什么您可以通过在单一时间内提供流程“实时”优先级来冻结您的计算机的原因)

在Linux下,也会定期安排较低优先级的流程,而不是经常安排。

但是你能做的最好的事情通常就是假设操作系统能够找到一个公平的方案,然后尝试与系统的其余部分一起玩。 (当你无事可做时,产生/阻止/睡眠,允许其他线程运行)。

  

线程是否从一个核心移动到   在他们的一生中另一个?

当然。想象一下,您在双核系统上运行了三个线程。向我展示一个公平的时间表,不涉及在核心之间定期移动线程。

  

我的最后一个问题,基本上就是这样   重用上面的,是关于   .NET ThreadPool类,它处理   像.BeginInvoke之类的东西。   这堂课有没有做过这些?   如果没有,为什么不,或者应该呢?   什么东西?线程调度和选择要运行的核心?不,线程池只是一种机制,可以为多个任务重用线程,而不必为每个任务创建一个新线程,然后再关闭它。

     

有没有办法调整这个   处理,有点暗示   这个特别的操作系统   螺纹

这就是线程/进程优先级的用途。如果你有一个必须获得大量CPU时间的线程,即使有其他CPU密集型线程在运行,也要提高线程的优先级。 但要小心处理。通常,没有很多CPU密集型线程在运行,这意味着即使在正常优先级下,您也将获得99.9%的CPU时间。正如我所说,Windows会非常积极地安排更高优先级的线程,因此只有在真的意味着它时才会提高优先级。

答案 1 :(得分:6)

除了jalf的优秀和全面的答案,请记住“并行扩展”(应该归入.NET 4.0)有一个很多代码专用于分配工作(来自队列)统一核心,包括工作窃取,以及潜在的金块,如关心哪个核心“最接近”工作所在的记忆。

因此,使用.NET 4.0,使用Parallel.For之类的东西,你应该免费获得很多这样的东西。一般来说,操作系统非常聪明,它可以从外人的角度来看正常工作。 jalf已经提供了很多关于幕后发生的事情的详细信息,但大多数当时你不需要这个级别的细节,除非你用高度线程化的代码解决了一些性能问题。< / p>