确定C#Partitioner.GetPartitions()的分区计数的因素
下面是确定C#Partitioner.GetPartitions()的分区计数的因素,c#,asynchronous,async-await,task-parallel-library,C#,Asynchronous,Async Await,Task Parallel Library,下面是ForEachAsync 公共静态任务ForEachAsync(此IEnumerable源代码,int-dop,Func-body) { 返回任务。当所有( 从Partitioner.Create(source).GetPartitions(dop)中的分区 选择Task.Run(异步委托{ 使用(分区) while(partition.MoveNext()) 等待体(partition.Current); })); } 指定分区计数时应考虑哪些因素(dop) 硬件是否有区别(内核、
ForEachAsync
公共静态任务ForEachAsync(此IEnumerable源代码,int-dop,Func-body)
{
返回任务。当所有(
从Partitioner.Create(source).GetPartitions(dop)中的分区
选择Task.Run(异步委托{
使用(分区)
while(partition.MoveNext())
等待体(partition.Current);
}));
}
指定分区计数时应考虑哪些因素(dop
)
硬件是否有区别(内核、可用RAM等)
数据/操作的类型是否影响计数
我的第一个猜测是将
dop
设置为等于环境。对于一般情况,ProcessorCount
,但我的直觉告诉我这可能是不相关的。硬件和执行的操作都非常重要
如果您想运行CPU绑定的工作,而不受任何其他方式的约束,则根本不需要使用该方法。您最好使用Parallel
或PLINQ
,它们都是为此而设计的(而且在IO上非常糟糕)
对于IO来说,没有简单的方法可以预测最佳DOP。例如,像DOP1这样的磁盘。类似于4-16(?)的固态硬盘。Web服务几乎可以拥有任何价值。我可以继续列出更多因素,包括数据库、锁争用等
您需要在测试环境中测试不同的量。然后,使用最佳性能值
使用Environment.ProcessorCount对IO没有任何意义。添加CPU时,IO不会变快。DOP值会影响硬件。你可以给DOP任何可行的值 您一次为多个并行代码进程提供的值
例如,如果数据集中有1000行,则需要处理每行并对其执行特定操作。现在,如果DOP值为50,那么每次50行将并行处理。您反对将其用于IO的论点是有道理的。但是为什么(具体地说)使用
Parallel
或PLINQ
比使用async await
的扩展更好呢?我认为它们有不同的方法来生成线程。此代码将始终生成N,而Parallel具有在线程池饱和时生成较少的规定。不过,我不确定这有多重要。在任何情况下,异步对于CPU受限的工作来说都是毫无意义的。感谢您解释每种类型问题的用例:CPU vs.IO vs.外部(想想HTTP请求)。
public static Task ForEachAsync<T>(this IEnumerable<T> source, int dop, Func<T, Task> body)
{
return Task.WhenAll(
from partition in Partitioner.Create(source).GetPartitions(dop)
select Task.Run(async delegate {
using (partition)
while (partition.MoveNext())
await body(partition.Current);
}));
}