I have some code which I am currently optimizing for concurrency in multicore architectures. In one of my classes, I found a nested foreach
loop. Basically the outer loop iterates through an array of NetworkInterface
objects. The inner loop iterates though the network interfaces IP addresses.
It got me thinking, is having Nested Parallel.ForEach
loops necessarily a good idea? After reading this article (Nested Parallel.ForEach Loops on the same list?) I am still unsure what applies where in terms of efficiency and parallel design. This example is taking about Parallel.Foreach
statements being applied to a list where both loops are performing operations on that list.
In my example, the loops are doing different things, so, should I:
The nesting operator: %:% I call this the nesting operator because it is used to create nested foreach loops. Like the %do% and %dopar% operators, it is a binary operator, but it operates on two foreach objects. It also returns a foreach object, which is essentially a special merger of its operands.
Every now and then, I get this question: “is it ok to use nested Parallel. For loops?” The short answer is “yes.” As is often the case, the longer answer is, well, longer.
OpenMP parallel regions can be nested inside each other. If nested parallelism is disabled, then the new team created by a thread encountering a parallel construct inside a parallel region consists only of the encountering thread. If nested parallelism is enabled, then the new team may consist of more than one thread.
It's not uncommon to break the execution of a for/foreach loop using the 'break' keyword. A for loop can look through a list of integers and if the loop body finds some matching value then the loop can be exited. It's another discussion that 'while' and 'do until' loops might be a better alternative, but there you go.
A Parallel.ForEach does not necessarily execute in parallel -- it is just a request to do so if possible. Therefore, if the execution environment does not have the CPU power to execute the loops in parallel, it will not do so.
If the actions on the loops are not related (i.e., if they are separate and do not influence each other), I see no problem using Parallel.ForEach both on inner and outer loops.
It really depends on the execution environment. You could do timing tests if your test environment is similar enough to the production environment, and then determine what to do. When in doubt, test ;-)
Good luck!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With