LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Set Number Of Parallel Loops Programmatically

When configuring a For Loop with parallelism, is there a way to set the "Number Of Parallel Loop Instances" programmatically? Here's my situation.

So lets say I have a for loop with parallelism turned on. In the For Loop I have a wait 100ms which is independent of all other loops. So in my mind I want there to be N parallel loops, one for each iteration so that each can wait the 100ms and the entire for loop can take 100ms (plus or minus a few milliseconds).

So how do I do this? Well you wire your array of things into the for loop auto indexing which defines how many times the loop runs. You can also wire the array size to the P terminal, or wire a -1 which should mean all according to the help. But here is the problem. By default when you configure parallelism you tell it in the configuration window the Number of Generated Parallel Loop Instances. Here if you set the size to less than the number of array iterations, then the wait won't be more than 100ms by at least double.

The attached VI describes what I'm talking about. Where the first time test shows that if Number Of Devices is 8 or less, the wait is 100ms, and for Time Test 2 if the number is 12 or less the wait is 100ms. But what I would really like is a for loop that doesn't need to have a hard coded constant for the number of for loops it will spawn. Just spawn as many iterations as the input array. Is this possible or is there some compiler reason, that this upper bounds needs to be known at run-time?

0 Kudos
Message 1 of 6
(3,065 Views)

In the LabVIEW help under "Configuring Parallel For Loop Iterations to Tweak Performance", I noticed it says:

 

"At compile time, LabVIEW generates a number of parallel instances equal to the minimum of the value provided in the Number of generated parallel loop instances field of the For Loop Iteration Parallelism dialog box and the value wired to the input of the parallel instances terminal. "

 

Your first for loop is set (in the dialog) to 8, while the second is set to 12.  Increasing them to 20 makes them work up to arrays of 20.

 

It also suggests that parallel instances are set up at compile time, and so can't dynamically size themselves to the number of array elements.

 

Message 2 of 6
(3,043 Views)

Scripting provides the "NumStaticParInstances" property, but that comes with all of the caveats VI scripting normally does. 

Tom L.
Message 3 of 6
(3,040 Views)

I did not know that scription function was exposed, but yeah it doesn't help in this situation.  I was trying to imagine a way to make my code more modular, by being able to set this at run-time, but if the compiler needs to know this then the best I can do is set it to as large of number as I feel comfortable with.  In this case that would likely be in the range of 30 or so.  I can round to 32 in the assumption that we all have 32 core machines in the future.

0 Kudos
Message 4 of 6
(3,029 Views)

I belive you should be able to do something like this by opening N "worker" VIs containing your for loop logic using the Start Asyncronous Call function in a for loop and collecting the results using a named queue or a second for loop containing the Wait on Asynchronous Call function.

 

The dispatch and collect aren't truly parallel and you might need to track which results came from which worker (if you're using a queue and it matters), but it should scale well.  Influencing core affinity for each instance of the worker might be another hurdle but I haven't looked into it.

 

Example (haven't tried it, but either way should work):

 

WorkerDispatch.png

 

 

Tom L.
0 Kudos
Message 5 of 6
(3,011 Views)

My understanding is that the for loop parallelism is just autoscripting a bunch of loops in the intermediate language, so yes I think the compiler has to know. Also, whatever code is going to be duplicated N times which can lead to suffering if the diagram gets too big and the compiler gets bogged down, so be careful there. I think the only truly dynamic way to do this is with the start async call method. If you do, be sure to set the call pool size up front.

0 Kudos
Message 6 of 6
(2,976 Views)