C# 带并行度(N>;CPU计数)
在我的系统中,线程数从未超过CPU数。 我可以使用PLINQ并在每个CPU上获得多个线程吗?简短回答:不可以 线程的数量取决于.Net Framework运行时。没有用于控制TPL(任务并行库)使用的线程数的开发人员控件 编辑 多亏了其他一些反馈:实际上可以(但不推荐)手动控制线程池中的线程数量,PLINQ和TPL使用这些线程 我认为,任何并行化问题都需要仔细考虑、仔细构造和测试。这里面有很多微妙之处。简短回答:不 线程的数量取决于.Net Framework运行时。没有用于控制TPL(任务并行库)使用的线程数的开发人员控件 编辑 多亏了其他一些反馈:实际上可以(但不推荐)手动控制线程池中的线程数量,PLINQ和TPL使用这些线程C# 带并行度(N>;CPU计数),c#,plinq,C#,Plinq,在我的系统中,线程数从未超过CPU数。 我可以使用PLINQ并在每个CPU上获得多个线程吗?简短回答:不可以 线程的数量取决于.Net Framework运行时。没有用于控制TPL(任务并行库)使用的线程数的开发人员控件 编辑 多亏了其他一些反馈:实际上可以(但不推荐)手动控制线程池中的线程数量,PLINQ和TPL使用这些线程 我认为,任何并行化问题都需要仔细考虑、仔细构造和测试。这里面有很多微妙之处。简短回答:不 线程的数量取决于.Net Framework运行时。没有用于控制TPL(任务并行
我认为,任何并行化问题都需要仔细考虑、仔细构造和测试。这其中有很多微妙之处。PLINQ使用爬山算法来确定TPL使用的线程池的最佳大小。我认为,如果在任务中投入大量I/O,那么可以看到比cpu数量更多的线程
也就是说,我从未见过比cpu数量更多的线程:)。但也许我从来没有遇到过正确的情况。PLINQ使用爬山算法来确定TPL使用的线程池的最佳大小。我认为,如果在任务中投入大量I/O,那么可以看到比cpu数量更多的线程
也就是说,我从未见过比cpu数量更多的线程:)。但也许我从来没有遇到过正确的情况。如果调用外部web API,可能会达到并发连接的极限,即设置为2。在应用程序开始时,请执行以下操作:
System.Threading.ThreadPool.SetMaxThreads(50, 50);
File.ReadLines().AsParallel().WithDegreeOfParallelism(100).ForAll((s)->{
/*
some code which is waiting external API call
and do not utilize CPU
*/
});
如果有帮助的话,试试看。如果没有,那么在您尝试并行化的例程中可能存在其他瓶颈
另外,正如其他响应者所说,ThreadPool根据负载决定要启动多少线程。在我使用TPL的经验中,我发现线程数量随着时间的推移而增加:应用程序运行的时间越长,负载越重,线程就越多。如果调用外部web API,可能会达到并发连接的限制,即设置为2。在应用程序开始时,请执行以下操作:
System.Threading.ThreadPool.SetMaxThreads(50, 50);
File.ReadLines().AsParallel().WithDegreeOfParallelism(100).ForAll((s)->{
/*
some code which is waiting external API call
and do not utilize CPU
*/
});
如果有帮助的话,试试看。如果没有,那么在您尝试并行化的例程中可能存在其他瓶颈
另外,正如其他响应者所说,ThreadPool根据负载决定要启动多少线程。在我使用TPL的经验中,我发现线程数量随着时间的推移而增加:应用程序运行的时间越长,负载越重,线程就越多。我用以下代码对此进行了测试:
System.Net.ServicePointManager.DefaultConnectionLimit = 4096;
System.Net.ServicePointManager.Expect100Continue = false;
基本上,它记录当前并发执行的迭代次数,然后保存遇到的最大值
结果相差很大,在15到25之间,但总是比我的计算机拥有的CPU数量(4)多得多。增加睡眠时间会增加并发线程的最大数量。因此,这里的限制因素似乎是ThreadPool
:它将缓慢地创建新线程,特别是当作业相对较快地完成时
如果要增加使用的线程数,则需要使用SetMinThreads()
(而不是SetMaxThreads()
)。如果我将最小值设置为50,那么实际使用的线程数大约为60
但是有几十个线程除了等待什么都不做,这是非常低效的,特别是在内存消耗方面。应该考虑使用异步方法。 我用以下代码测试:
System.Net.ServicePointManager.DefaultConnectionLimit = 4096;
System.Net.ServicePointManager.Expect100Continue = false;
基本上,它记录当前并发执行的迭代次数,然后保存遇到的最大值
结果相差很大,在15到25之间,但总是比我的计算机拥有的CPU数量(4)多得多。增加睡眠时间会增加并发线程的最大数量。因此,这里的限制因素似乎是ThreadPool
:它将缓慢地创建新线程,特别是当作业相对较快地完成时
如果要增加使用的线程数,则需要使用SetMinThreads()
(而不是SetMaxThreads()
)。如果我将最小值设置为50,那么实际使用的线程数大约为60
但是有几十个线程除了等待什么都不做,这是非常低效的,特别是在内存消耗方面。你应该考虑使用异步方法代替。PLUNQ不适合这种情况。 我发现下一篇文章对我很有用。
PLINQ不适合这种情况。 我发现下一篇文章对我很有用。
这有什么意义?性能不会提高。@GSerg:如果出现某种阻塞IO,性能可能会提高。不推荐。如果我是你,我会调查TPL数据流。或者如果你想使用纯TPL,请查看Parallel.For和Parallel。ForEach@Vladimir这就是阻塞IO的定义;您启动一个IO操作,然后让一个线程坐在那里不做任何事情等待它完成,而不是使用异步,这样您就可以在操作完成时做一些事情,而不用让一个线程等待该操作。@Vladimir:I'm not blocking IO.语句直接与“每个任务只会将请求发送到外部慢速API,并等待~3秒以获得响应”。您在IO上阻塞了~3秒。这有什么意义?性能不会提高。@GSerg:可能可以