09-12-2014 02:27 PM
@SergeB wrote:
Interesting! Thanks for the elaborate explanation!
If I am understanding things right, your theory seems to explain things if all 3 units are exchanging messages on the same COM port? Or am I looking at this the wrong way?
I have 1 COM port/unit so that means 24 COM ports.
thanks,
Serge
That rate was for 1 COM port period. If you have separate ones, then is could become an issue with your processing.
I'm not totally sure if VISA is reentrant. If it isn't, then you are back to the issue Lynn gave you.
09-12-2014 02:58 PM
Serge,
What kind of device(s) do you have to provide the 24 COM ports? How does it connect to the computer?
Look at the Detailed Help for VISA Read and Write for the comments on synchronous and asynchronous operations. Something there may be useful.
Lynn
09-14-2014 10:31 PM
In answer to Crossrulz -
VISA (serial at least) is fully reentrant as far as I understand. I have test stations with upwards of 60 com ports, all connected to DUTs spewing 6400 chars/second each; all consumed by (somewhat carefully crafted) reentrant LabVIEW code. If VISA weren't reentrant, I'd never be able to do that.
Having a single for loop with parallelism set (if I understand the original poster's description) doesn't sound like a feasible architecture for scaling up. I'm not at all certain the compiler generates parallel execution the way it is needed here, given that there is I/O on the for loop subdiagram, and the extent to which it can is, I suspect, strongly dependent on the CPU architecture (read: number of cores) it finds itself running on.
I create one VI that does all the serial port interaction, set it reentrant (and generally ditto for any subVIs it calls), then clone that code by calling it thru an ACBR inside a for loop, where the com port reference is part of the unique data that is passed. Then of course there must be some mechanism in place for doing useful things with the stuff being processed. Generally, I post messages (via queue or user event architecture) back to a"visualizer" (which is a lousy term but the only one I can think to call it right now). You can even have the clones send back a VI reference to themselves and have the "visualizer" select one (under user control) to place into a subpanel.
Serial hardware to scale up to this number of ports is loosely termed "terminal servers", one such vendor is Digi. Sixteen or thirty two ports in a box isn't uncommon.
Dave
09-15-2014 04:49 PM
09-15-2014 05:28 PM - edited 09-15-2014 05:30 PM
@SergeB wrote:
Yes David (and crossrulz) you are right, I am using two DIGI 16 ports modules (16em 232 CR2) for my COM ports.
I think I have my code the way you are descibing it but I don't know what ACBR means? I have attached a .png of the basic archtitecture.
Thanks,
Serge
Google says that "LabVIEW ACBR" is "Asynchronous Call by Reference".
I agree with @DavidBoyd that using a For Loop with Parallelism enabled isn't really the way to go here. Instead of having them being done one at a time as in a traditional For Loop, you now do them n amount at a time where n = the number of cores on your computer. It would be better to have your code be reentrant and have n amount of loops, one for each port. (That would be the brute-force method. David's idea is more elegant.) That way, LabVIEW can execute the code the way it wants to with all your code running optimized and parallelized.
09-15-2014 06:22 PM
SergeB,
Sorry, yes, ACBR is Asynchronous Call By Reference. The preferred way (since LV 2009? 10? I forget) to launch multiple instances of a VI without waiting for it to complete. Much cleaner semantically than the old method, which involved programmatically setting control values (brittle because you specified the control names, and values by variant) and invoking "Run VI", within the loop.
I don't even know if you get N simultaneous runs of your VI inside the parallel for loop, just because you've got N cores, because the compiler might not assume they're "safe" to call in parallel (i.e, no side effects).
Doing the architecture I'm alluding to takes more effort, if you need to interact with the clones while they're running, because you need asynchronous messaging (queues, notifiers, user events are all possibilities here) to pass data between the invoking VI and clones.
If you DON'T need to interact with them, and can wait for them to finish, architecture is much simpler. There is a companion node to the ACBR (aka "Start Asynchronous Call") which is "Wait On Asynchronous Call", right next to it on the Programming->Application Control palette. Your pattern would be something like:
get an appropriately prepared reference to your VI (Open VI Reference with flags for call-and-collect|enable-simultaneous-calls);
do the "Start Asynchronous Call" in a loop;
wait for....whatever it is you're expecting to happen...
do the "Wait On Asynchronous Call" in a loop (the same number of times)
mop up the VI reference(s).
You need to pass out some unambiguous value that tells you which clone is which (if it matters), since the "Wait" node returns the results in no particular order.
You'll definitely want to look at some of the shipping examples here - plenty of ways to hurt yourself (he said from experience).
Good luck!
Dave
Dave
09-23-2014 08:56 PM
09-26-2014 02:04 PM
Hi Billko,
Must of missed your post somehow. The png file I had shown was for parralelism with reentrancy enabled, which was the brute force method you were referring to. This brute force method works when testing with 2 DUTs but with 3 more DUTs, it is not sufficient anymore because the acquisition sample rate slows down with each additional DUT.
-Serge
09-26-2014 02:19 PM
Hey David,
So I think I am having trouble understanding this ACBR thing a little.
I tried following the shipping examples and your suggestions but it's making my sample rate even slower than before so I must not understand how to optimize this.
I have attached a .png of my code. The Device Ports cluster and the Input Data Cluster both contain 6 elements, one for each DUT.
Basically, I need to acquire 500 samples in 50 secs. In my code I set the number of asychronous call to the number of DUTs so that means I get 6 samples once the "Wait on Asynchronous Call" returns if I am testing 6 DUTs. I then keep looping this code over and over until the number of samples received is sufficient. I also tried to see what would happen if I increased my number of asynchronous calls to like 24 and then iterate through my 6 COM ports 4 times but no luck there either.
Please help.
Thanks,
Serge
09-28-2014 08:33 AM