NI TestStand

cancel
Showing results for 
Search instead for 
Did you mean: 

Executing VI's using Teststand parallel model - LabVIEW design considerations

Hi all,

 

I’m trying to find / create a concise list of design rules that should be applied when creating LabVIEW modules for TestStand sequences that will be run in parallel using the parallel batch process model. Areas of interest include: un-initialised shift registers, regular LabVIEW globals, re-entrant Vis.

 

Using LabVIEW 8.5 & TestStand 4

 

TIA

 

-Martin

Certified LabVIEW Architect
0 Kudos
Message 1 of 11
(7,379 Views)

HI Martin,

 

When using either the batch or parallel process model with more than 1 test socket, we ensure a multithreaded domain. This can also exist when using a parallel testing architecture (ie. running sequences in their own threads or executions) with the sequential process model. So with any process model it is important to realize that it is possible to be in a multithreaded domain that provides shared access to resources. Without writing a dissertation on the advantages and caveats of multithreading, it should suffice to say that anytime shared access to resources is available we must synchronize the access to those resources to avoid deadlocks and race conditions.

 

The abstract answer to your question:

 

During the design of multithreaded modules (your LabVIEW code that will be called in a possibly multithreaded domain) you should realize that at any point during execution of your code the operating system may give up the current time-slice in which a thread is executing and give it up to another thread that could possibly enter execution anywhere. This awareness should lead to identifying certain critical sections of code that should be run atomically (no chance of half-completion). These critical sections are the pieces of code that should be synchronized. LabVIEW provides synchronization mechanisms designed to manage resource protection and sharing among multiple threads.

 

Some of the key resources requiring syncronization to keep in mind are (in decreasing order of locality): application resources (ie. any global data accessed in your LabVIEW code modules or parallel instances of one module if re-entrant), resources shared among processes (ie. file access), and system level resources (ie. instruments, communication ports, etc.).

 

More specifically:

 

  • Non re-entrant VIs will execute atomically. If multiple threads attempt to run a non re-entrant VI, the first to begin execution must finish before any subsequent thread begins execution.
  • Function Globals, or LV2 style globals keep information thread-safe. Their non re-entrant behavior ensures atomic execution, which will avoid any internal race conditions that could corrupt their contained data.
  • LabVIEW globals are not thread-safe. Without using synchronization mechanisms when accessing a LabVIEW global, the data cannot be guaranteed to be valid when multiple threads have access to it as race conditions can easily exist.
  • Re-entrant VIs will result in faster parallel tests. With multiple test sockets, TestStand will attempt to exeute many code modules in parallel. LabVIEW can execute multiple instances of re-entrant VIs at once in their own code space. If your modules are re-entrant, multiple test sockets will not have to wait on other test sockets to finish execution of a VI before they can begin their execution of the same VI.
    • Keep in mind this is true at any hierarchical level in your code.  For optimal execution speed, within a re-entrant VI, as many sub-VIs as possible should be re-entrant, so execution will block as infrequently as possible across multiple test sockets.
  • TestStand should be in control of execution flow. The more you are able to develop code modules that are highly cohesive (have one purpose) the easier and more efficient development will be.
    • Making your code modules as asynchronous possible will result in the most efficient use of system resources. Following this recommendation will help you see the largest gains in parallel testing and will help take full advantage of multicore systems.
    • When synchronous behavior is needed, synchronizing inside your TestStand sequence will help keep your modules as asynchronous as possible. TestStand has its own synchronization objects for coordinating the execution of multiple test sockets. In general, it is recommended to use these objects in your sequence as opposed to trying to synchronize the execution of multiple threads within code modules.

 


While this is not an all inclusive list of recommendations for successful multithreaded module development, hopefully this will spark anyone else to put their two cents in and will also help get you started in forming of a list of design best practices. If any of the points I've mentioned above remind anyone of lessons they have learned in the course of thier development, it would be very helpful to post explanations of your specific examples to give everyone a feel for how these recommendations and concepts might actually apply to them.

Message Edited by Evan P. on 12-03-2008 11:45 AM



Evan Prothro
RF Systems Engineer | NI

Message 2 of 11
(7,303 Views)

Thank you for such a detailed answer to this question Evan. This information is very much appreciated.

 

-Martin

Certified LabVIEW Architect
0 Kudos
Message 3 of 11
(7,280 Views)

Does anyone know if it is possible to share Functional Globals across test sockets when executing using the Parallel Process Model?

 

What I'm seeing is that, even if the VI housing the Functional Globals is re-entrant, each test socket will open up a unique version of the VI.

 

Is there a way to force them to use the same copy?

 

Thanks,

 

Tom

0 Kudos
Message 4 of 11
(5,826 Views)

Tom,

 

FGVs must not be reentrant. So please check the setting of the FGV itself.

 

hope this helps,

Norbert

Norbert
----------------------------------------------------------------------------------------------------
CEO: What exactly is stopping us from doing this?
Expert: Geometry
Marketing Manager: Just ignore it.
0 Kudos
Message 5 of 11
(5,813 Views)

Hi Tom,

 

If you would like a more comprehensive reply to your question please create a new thread. The initial question in this thread has already been answered so you will get a better response from the community by making a new question.

 

Many thanks,

Mahdieh G
Applications Engineer
National Instruments UK&Ireland
0 Kudos
Message 6 of 11
(5,809 Views)

Thanks Norbert,

 

I thought that would be the case too, but it appears that seperate teststand executions do not share the same copy of the re-entrant VI.

0 Kudos
Message 7 of 11
(5,797 Views)

Re-entrant VIs are never shared. Not in LV, not in TS.....

 

The FGV MUST NOT BE RE-ENTRANT.

 

Norbert

Norbert
----------------------------------------------------------------------------------------------------
CEO: What exactly is stopping us from doing this?
Expert: Geometry
Marketing Manager: Just ignore it.
0 Kudos
Message 8 of 11
(5,771 Views)

It looks like I misunderstood your first post.  Can you explain how to make a FGV without making it re-entrant?

0 Kudos
Message 9 of 11
(5,766 Views)

@twilson1111 wrote:

It looks like I misunderstood your first post.  Can you explain how to make a FGV without making it re-entrant?


Thats like asking how to make apples that are oranges.  If the vi is re-entreant it is not a FGV since a FGV is defined as a vi with a USR that has only one copy of itself in memory.  By making it places at least TWO clones in memory and there is no way to share the data on both shift registers. 

 

There are two methods.  With Pre-allocate clones each call in each test socket will have its own clone

With Share Clones Clones are spawned as needed so that no calls are ever blocked.  Your test step module loading/unloading options will determine when the clone "cloud" spawns new clones (as they are reserved not as they are called from the sequence)


"Should be" isn't "Is" -Jay
0 Kudos
Message 10 of 11
(5,751 Views)