C# 任务并行库如何执行负载平衡?
我们都知道,为了真正执行异步操作,我们的机器必须有多个内核,每个内核都将运行自己的线程来执行自己的任务 让我们从一个例子开始,我们有一个四核cpu和4个任务。为了使用C以真正的并行方式运行我们的四个任务,我们必须分别创建和运行四个任务,如下所示:C# 任务并行库如何执行负载平衡?,c#,multithreading,task-parallel-library,multicore,multitasking,C#,Multithreading,Task Parallel Library,Multicore,Multitasking,我们都知道,为了真正执行异步操作,我们的机器必须有多个内核,每个内核都将运行自己的线程来执行自己的任务 让我们从一个例子开始,我们有一个四核cpu和4个任务。为了使用C以真正的并行方式运行我们的四个任务,我们必须分别创建和运行四个任务,如下所示: publicstaticvoidmain() { //定义并运行任务。 任务[]任务={ Task.Run(()=>WorkA()), Task.Run(()=>WorkB()), Task.Run(()=>WorkC()), Task.Run
publicstaticvoidmain()
{
//定义并运行任务。
任务[]任务={
Task.Run(()=>WorkA()),
Task.Run(()=>WorkB()),
Task.Run(()=>WorkC()),
Task.Run(()=>WorkD())
}
Task.WaitAll(任务);
}
在本例中,TPL将为每个任务提供来自线程池的线程,并尽可能在不同的处理器中运行每个线程。(我希望我是对的)
场景:
假设我们有四核cpu和6个任务,我们编写了以下代码:
publicstaticvoidmain()
{
//定义并运行任务。
任务[]任务={
Task.Run(()=>WorkA()),
Task.Run(()=>WorkB()),
Task.Run(()=>WorkC()),
Task.Run(()=>WorkD()),
Task.Run(()=>WorkE()),
Task.Run(()=>WorkF())
}
Task.WaitAll(任务);
}
TPL是否会知道线程的最佳充足数量,并安排其中的任务?(考虑核心状态和任务负载差异)
例如:
- 总共3个线程-每个线程2个任务。(假设一个核心忙)
- 总共4个线程-3个线程-每个线程1个任务,最后一个线程3个任务 一个
- 总共6个线程-每个线程1个任务
Task.Run()
将任务添加到全局队列。假设您的池中已经有4个空闲线程,那么它们将尝试从全局队列中获取任务,这是一个涉及同步和锁定的操作。根据每个任务的工作负载,只让一个或两个线程处理所有任务可能更有效。如果池中只有一个线程呢?再创建3个线程可能比单线程执行任务的成本更高。当然,这些信息在运行时不可用。任务调度器永远不会知道什么是最佳策略。当他知道已经太迟了,因为工作已经完成了。因此,有很多猜测,测量cpu内核的工作负载和任务创建选项。这就是全部-没有未来的前景或任何内置的魔法任务调度器是一个通用工具,它试图在不知道要做什么工作的情况下尽可能快地完成工作。如果您更了解自己的工作和负载,那么您应该构建自己的专用线程驱动作业工人,以获得最后的性能百分比:o)扩展Rufo爵士的有效观点是,由于显式创建的线程的每个线程开销,线程的启动成本很高。使用内置任务线程池允许在重新使用内置线程池的同时创建许多较小的较短任务,并将代码从管理线程池、调度和同步等方面解放出来。因此,如果有1000个无关任务,请使用内置线程池。如果您有5个独立的200个相关操作组,请使用您自己的5个线程池。