Not sure if this should go in the TestStand or Labview board, so I'll try TestStand first......
I'm building a TestStand test rig that's using the Parallel process model. I want to replace the standard uut dialogue with a custom dialogue built using Labview (as an aside, the test rig requirement needs custom barcode entry screens).
I have a working system now. Basically I set the TestStand ModelOptions parameter "ParallelModel_ShowUUTDlg=False", and interact with my own Labview UUT Dialogue in the PreUUT and PostUUT callbacks. I send data from TestStand>>Labview using wrapper vis around standard Labview sychronisation objects. These work lightning fast!
The main issue was how to cleanly get information from my Labview UUTDialogue (barcodes and control tags etc), back into each TestStand parallel execution, i,e. Labview>>TestStand. I have successfully done this by connecting to the Synchronisation Manager and Enqueueing my messages to the relevant TestStand execution. I've attached my Labview VI that does this task.
This works but my only issue is the speed of the Enqueue call (specifically the IQueue.Enqueue invoke node). This single steps takes about 1 second to execute each time. I've tried setting the "processMsgs" parameter to true but this doesn't help. Calling the invoke nodes to the NewPropertyObject, the SynchManager and the GetQueue are fast. Only the Enqueue invoke node is slow.
Everything else seems to work as expected - all data structures pass into the TestStand parallel executions as intended. Any ideas why the Enqueue is so slow?
Solved! Go to Solution.
Thanks for the reply. I had already found that link.
I'm transferring data in the reverse direction - using the synchronisation manager in Labview and sending data to TestStand. My only issue is each Enqueue operation takes about 1second. This timing stays consistent, i.e. subsequent Enqueues take 1 second. The dequeue in TestStand is fast (using TestStand's native dequeue).
As per your reply on the other thread, if I use Labview wrapper vis around standard Labview synchronisation objects everything is fast. However I want to send to a native TestStand Queue, and the only way I can accomplish this is to interact with the synchronisation manager in Labview.
I have a couple of thoughts and questions that might be helpful. First, what's the data type youre passing using the queue? It looks like just a string, but I wanted to be sure. Also, I'm wondering if passing the data by reference might be faster than passing the data by value? You could try it. Also, does the Write to TestStand Queue VI get called from TestStand, or is it somehow running asynchronously? If it's called from TestStand, I think you need an input other than a null reference for the sequenceContextObj input. In case you haven't looked it over, you could check the TestStand Help for the Enqueue method here: http://zone.ni.com/reference/en-XX/help/370052P-01/tssyncserver/reftopics/queue_enqueue_m/
As a general note, comparing your code to the example here: http://www.ni.com/example/30108/en/ (yes, that's a Dequeue example, not Enqueue) it looks like you're leaving some references unclosed. Specifically, the IEngine reference and the ISyncManager. It would probably be good practice to close those references, even if it doesn't affect the execution time.
EDIT: Also found this thread here that looks like it had a working implementation, you could try looking over the code here and see if you can spot any differences: http://forums.ni.com/t5/NI-TestStand/Using-Sync-Manager-for-LabVIEW-OI-exe-amp-TestStand/td-p/281362...
The Sync Manager Experiment III zip seems like it was the most complete.
Applications Engr., National Instruments
Thanks for the reply Cason,
The "write to teststand queue.vi" is called from within a Labview vi, which is in turn launched by TestStand in a new thread (the vi is a replacement for the standard parallel model UUT Dialogue).
The IEngine reference is passed in from TestStand as Runstate.Engine when it launches the vi. I didn't close this reference as I had assumed TestStand created it. I also use this reference multiple times in my Labview vi, so would have to release it when I finally close the vi (this vi runs continuously and provides the TestStand UUT Dialogue). I note your point about closing the ISynchManager reference, I had simply copied this from other examples I found.
The data type I'm passing back to TestStand, is a TestStand container which has two strings (called "parameter" and "data").
I'll study your links, and see if I can understand the invoke calls better, specifically the SequenceContextObj input to IQueue.Enqueue.
Just had a look at the link with the attachment "Synch Manager Experiment III.zip", posted by "hans17". I remembered that I used this very link to get my example working. This example also passes a null reference into the Enqueue.SequenceContextObj method, which is why I did the same.
I do note the example closes the ISynchManager reference though, so I should fix that. I'm also creating a property object, as the TestStand variable is not a simple string, but instead I'm enqueueing into a TestStand container that holds two strings.
I had meant to ask this before: does this delay happen as soon as you start running the program? Or does it build up over time? Having a hard time finding much useful info on what you're seeing, or (honestly) much info on the SyncManager in general.
Applications Engr., NI
The delay happens immediately, and doesn't increase over time. The IQueue.Enqueue invoke node causes the problem, everything else (getting synch manage references etc), is very fast. I tried simplifying the data structures being passed (changed to a simple string type), but this had no effect.
However I've recently made progress on this issue. I've discovered that dropping the "*" from the queue name causes everything to run normally (i.e. fast). I was under the impression that I needed to add a "*" before the queue name because the Labview runtime engine was in a different process space than TestStand. However using normal inprocess queue names still works fine. I've tested TestStand calling both the Labview development environment and the Labview runtime engine. In both cases, queue names with the "*" prefix are slow (about 1 second), while queue names without the "*" prefix are fast (appear same speed as native LV synchronisation objects). I understand that the marshalling for out of process is longer, but didn't realise it was that bad.
That's an interesting discovery. I've seen a few references to global queues (with the asterisk) performing more slowly than local, but hadn't seen any mentions of THAT slow. Glad that you at least have found a workaround. I was initially thinking you were right, that LabVIEW and TestStand would be running in different processes, but I believe that's only true if you've configured the LabVIEW adapter to run in the Development environment. I think, if you're running the adapter in the run-time engine, then it's actually an instance of the RTE opened in the TestStand process. See the TestStand help here: http://zone.ni.com/reference/en-XX/help/373892E-01/tssemiconductor/performancelvrte/
"The TestStand LabVIEW Adapter can execute VI code modules in the LabVIEW development system process or in the TestStand process using the LabVIEW Run-Time Engine (RTE)"
And in this white paper: http://www.ni.com/white-paper/14335/en/
"By default, all VIs are called in the main application instance of the LabVIEW Run-Time Engine module loaded by the TestStand process"
So, IF you've configured your adapter to the RTE, then I think ti makes sense that you're able to access the queue without the asterisk. Of course, if you're running in the dev engine, then I would imagine you'd have to use a global queue. Hope this helps!
Applications Engr., NI
Re: Your comment;
"So, IF you've configured your adapter to the RTE, then I think ti makes sense that you're able to access the queue without the asterisk. Of course, if you're running in the dev engine, then I would imagine you'd have to use a global queue. Hope this helps!"
That's strange, because I can access the queue name without the asterix in both the Labview development and RTE environments. I had never tried this before, as I understood the same as you - that the dev environment was in a different process space.
Maybe you only need the asterix if you are running on a remote machine?