任务并行库如何执行负载平衡?

时间:2015-11-07 21:22:18

标签: c# multithreading task-parallel-library multicore multitasking

我们都知道,为了真正执行异步操作,我们的机器必须有多个核心,每个核心都会运行其自己的线程来执行其任务。

让我们从一个示例开始,我们有一个四核cpu 4个任务。为了使用 C#以真正的并行方式运行我们的四个任务,我们必须分别创建和运行4个任务:

public static void Main()
{    
   // Define and run the tasks.
   Task[] tasks = {
      Task.Run( () => WorkA() ),
      Task.Run( () => WorkB() ),
      Task.Run( () => WorkC() ),
      Task.Run( () => WorkD() )
   }

   Task.WaitAll(tasks);
}

在此示例中, TPL 将为每个任务提供来自 ThreadPool 的线程,并在可能的情况下在不同的处理器中运行每个线程。 (我希望我是对的)

情景:

假设我们有四核cpu 6个任务,我们编写了以下代码:

public static void Main()
{    
   // Define and run the tasks.
   Task[] tasks = {
      Task.Run( () => WorkA() ),
      Task.Run( () => WorkB() ),
      Task.Run( () => WorkC() ),
      Task.Run( () => WorkD() ),
      Task.Run( () => WorkE() ),
      Task.Run( () => WorkF() )
   }

   Task.WaitAll(tasks);
}

TPL 会知道什么是最好的线程数并在其中安排任务? (考虑核心的状态和任务的负载差异)

例如:

  • 总共3个线程 - 每个线程2个任务。 (可以说一个核心很忙)
  • 总共4个线程--3个线程 - 每个线程1个任务,最后3个任务 之一。
  • 共6个主题 - 每个主题1个任务。

TPL如何执行负载平衡?为了提供最佳的负载平衡,TPL考虑了什么。

1 个答案:

答案 0 :(得分:1)

  

TPL是否知道什么是最好的线程数量   安排他们之间的任务?

没有。这比你想象的要复杂得多:

Could not find autoprefixer-rails-6.1.0.1 in any of the sources Run `bundle install` to install missing gems. 将一个Task添加到全局队列中。假设您的池中已经有4个空闲线程,那么它们将尝试从全局队列中获取任务,这是一个涉及同步和锁定的操作。取决于每个任务的工作量,让一个或两个线程处理所有任务可能更有效。如果池中只有一个线程怎么办?创建3个线程可能比单个线程执行任务更昂贵。当然,这些信息在运行时不可用。