简体   繁体   English

控制 parallel.foreach 任务的执行顺序

[英]Control order of execution of parallel.foreach tasks

I have a list of table names (student, exam, school).我有一个表名列表(学生、考试、学校)。

I use a Parallel.ForEach loop to iterate over the table names and do processing for each table, with MaxDegreeOfParallelism = 8 .我使用Parallel.ForEach循环遍历表名并使用MaxDegreeOfParallelism = 8对每个表进行处理。

My problem is that my Parallel.ForEach doesn't always engage in work stealing.我的问题是我的Parallel.ForEach并不总是从事窃取工作。 For example, when two tables are left to process, they may be processed one after another instead of in parallel.例如,当两个表要处理时,它们可能会一个接一个地处理,而不是并行处理。 I'm trying to improve performance and increase throughput.我正在尝试提高性能并增加吞吐量。

I tried to do this by creating a custom TaskScheduler , however, for my implementation I need a sorted list of tasks with the easiest tasks ordered first, so that they aren't held-up by longer-running tables.我试图通过创建一个自定义TaskScheduler来做到这一点,但是,对于我的实现,我需要一个排序的任务列表,其中最简单的任务首先排序,这样它们就不会被运行时间更长的表所阻碍。 I can't seem to do this by sorting the list passed to Parallel.ForEach ( List< string > ) because the tasks are Enqueued by the TaskScheduler out-of-order.我似乎无法通过对传递给Parallel.ForEach ( List< string > ) 的列表进行排序来做到这一点,因为任务被TaskScheduler无序排入队列。 Therefore, I need a way to sort a list of tasks inside my CustomTaskScheduler, which is based on https://psycodedeveloper.wordpress.com/2013/06/28/a-custom-taskscheduler-in-c/因此,我需要一种方法来对我的 CustomTaskScheduler 中的任务列表进行排序,该列表基于https://psycodedeveloper.wordpress.com/2013/06/28/a-custom-taskscheduler-in-c/

How can I control the order in which tasks are passed by the Parallel.ForEach to the TaskScheduler to be enqueued?如何控制Parallel.ForEach将任务传递给TaskScheduler以进行排队的顺序?

The Parallel.ForEach method employs two different partitioning strategies depending on the type of the source. Parallel.ForEach方法根据源的类型采用两种不同的分区策略。 If the source is an array or a List , it is partitioned statically (upfront).如果源是一个数组或一个List ,它是静态分区的(预先)。 If the source is an honest-to-goodness ¹ IEnumerable , it is partitioned dynamically (on the go).如果源是诚实的¹ IEnumerable ,它是动态分区的(在旅途中)。 The dynamic partitioning has the desirable behavior of work-stealing, but has more overhead.动态分区具有工作窃取的理想行为,但开销更大。 In your case the overhead is not important, because the granularity of your workload is very low.在您的情况下,开销并不重要,因为您的工作负载的粒度非常低。

To ensure that the partitioning is dynamic, the easiest way is to wrap your source with the Partitioner.Create method:为确保分区是动态的,最简单的方法是使用Partitioner.Create方法包装您的源代码:

string[] tableNames;
Parallel.ForEach(Partitioner.Create(tableNames), tableName =>
{
    // Process table
});

¹ (The expression is borrowed from a comment in the source code ) ¹(该表达式是从源代码中的注释中借用的)

I would recommend looking up partitioners .我建议查找partitioners Managing threads on a Parallel loop has some overhead, so there is some built-in logic to try to keep this overhead small while still balancing the work across all cores propperly.在 Parallel 循环上管理线程有一些开销,因此有一些内置逻辑可以尝试保持这种开销很小,同时仍然适当地平衡所有内核之间的工作。 This is done by dividing the list into chunks and adjusting the chunk-size to hit some sweet-spot.这是通过将列表分成块并调整块大小以达到某个最佳位置来完成的。

I would guess that ordering the tasks as as smallest first will work against the paritioners balancing.我猜想首先将任务排序为最小将不利于分区器的平衡。 I would try ordering the work largest first if balancing is the goal.如果平衡是目标,我会尝试首先订购最大的工作。 Another thing I would try is to partition the work items with some constant chunk-size and see if that helps.我会尝试的另一件事是用一些恒定的块大小对工作项进行分区,看看是否有帮助。 Or perhaps even write your own partitioner.或者甚至可能编写您自己的分区程序。

I'm not sure it is a great idea to try to enforce some execution order.我不确定尝试强制执行某些执行顺序是否是个好主意。 Since you do not control the OS scheduler there cannot be any guaranteed ordering.由于您不控制 OS 调度程序,因此无法保证排序。 And even if you can make it more ordered, it would probably be at the cost of throughput.即使您可以使其更有序,也可能会以吞吐量为代价。

Also, if you are spending lots of time optimizing the parallelization, are you sure the rest of the code is optimized?此外,如果您花费大量时间优化并行化,您确定代码的 rest 是否已优化?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM