09-09-2009 10:04 AM - edited 09-09-2009 10:07 AM
Thanks for the explanation Dr. Damien.
I didn't know about the "clumps" but I knew that LabVIEW supports multithreading and the fact that several loops run in parallel is one of the main reasons I am using LabVIEW to build this application.
Actually, I will have all these loops running simultaneously, but that will be in one state of the whole state machine. This one state has data acquision, UI event handling, event commands and several more loops. That I know positively.
About SubVIs running with "reentrant" behaviour in parallel loops, yes, that's true. But I was referring to the SubVI (that you point which is called before these parallel loops), ExecutionLoop.vi, outside any of those loops and that would stop further processing until it finishes its work. I was referring to this behaviour. I don't know those green thick wires, if they are causing the behaviour like "start this subvi and while it runs, lets start next processes also" kind of thing.
I appreciate your recommendation. I had originally designed like that but then somehow I thought it would be better to have two event structures in two different states. These two states will actually deal with different sets of controls so there is no chance of event clashes. I know it's not a good design, but I thought to make loops less "heavy" like this, by separating functionalities into several loops. Perhaps I should reconsider the design. The thing is that certain loops need to be run only in one particular state (this can be handled by proper loop stoppers, that's also true).
And I appreciate your responses. Thanks for that.
09-10-2009 09:27 AM
The data acquisition loop VI does not connect to anything after itself except its cleanup VI. Thus, the other loops are free to execute while the acquisition loop is also executing. They all execute all the time in parallel. Position on the block diagram is unimportant. Flow dependency (what is wired to what) controls execution order and parallelism.
The main reason you do not want multiple event structures is that even if they are not active, they are still capturing events. So if you change to a new event structure, its first action will be to process all the events that occurred before you made it active, leading to some unpredictable behavior. Using one is a lot easier.
09-10-2009 10:14 AM - edited 09-10-2009 10:18 AM
Ok, so you mean, the Data Acquisition VI's output will not trigger another actions, so nothing/nobody is waiting for it to finish, yes?
Hmm, interesting. This means, I start a Datasocket VI and it will work and simultaneously the other loops will begin to work as well. Ok, I understood now. I thought it's in front of the other operation in the data flow. I know that the position on block diagram doesn't matter for execution flow, but I thought it's wired to someone's input.
So this is equal to some independent loop in the same vi. right? Good design to keep the code managable.
OK, in my case, I think I should have this loop in the same VI, because the data from datasocket will start some actions which would reflect on the front panel. so I think it should be in the same VI, for the sake of simplicity.
Yes, I do understand your point. Actually if you see the previously posted designs that I made, it shows the same thing (many loops in parallel), but I was just afraid to load so many loops in parallel. All this discussion was my attempt to understand if you're doing that in the same way or have a better way with reduced CPU expenses.
And, as a matter of fact, even after creating several Event Structures, I am still going to load those loops, and things would be redundant. Although, I would manage different states with different event structures successfully, because at each state the user sees only a certain set of controls, there would be redundancy in datasocket loop (that also has to be in all the states where i create event structure), apart from the bad design (multiple event structure).
So, yesterday I took a brave step, and considered your suggestion (I got convinced that there is no harm) and changed everything into what I had planned to do earlier and what you and Norbert have been suggesting me to do.
Now, I have a big loop, with a state machine, and there are just 3 states - Initialize, MainUIEvents, End.
That MainUIEvents has now events which were earlier handled in StartUIEvents, LoginUIEvents etc. (I think the names suggest what they did).
So everything like DS operations, Event structures and other loops for Video etc. happen here and the outgoing state is "End".
After highlighting execution, I saw that this case ends only after all the loops are ended, so there is no harm in directly putting End as the outgoing state without any conditions. I was afraid, that the outer loop executes all the times and in each cycle it would recheck the value and execute internal loop's next cycle. But in fact it's not the case. so I could boldly wire the End without any conditions.
I was afraid of loading the system with so many loops, but there is no other better way and I hope the user's system would support so many threads.
For now, I have avoided using PC in my program, because of comlexity in Queues closing. I am just going with the standard Event structure loops along with DataSocket's timed loops (because the Timed loop allows me to select a separate processor for that thread, apart from giving some rest of 200 ms to the system. I haven't connected any processor to that input node, since i donno abt the user's system, so it would automatically find the available processor. and I guess this is a benefit over the while loop with Wait function which would not select other processor, I guess.).
Any thing that raises eyebrows?
09-25-2009 09:54 PM
Hi there,
Today while thinking about my application's model, and thinking about producer-consumer in it. It is needed at some point, to not miss any new data in the datasocket, while an action is under process for the previous data. If I'm reading my datasocket register every 500 ms (if no new message appears before that), and if some message came there say during the 100th ms and it starts processing for that, and the process takes around 200 ms, and during these 200 ms, there were 2 more messages. So naturally the last data will be read when the loop comes back to the datasocket read node. For this reason, I would need a producer-consumer with a queue, that will continue enqueuing new messages while the old ones are processed in consumer (separate) loop. But this is another issue.
The question that came to my mind was, about my model. The one that i have finally implemented after discussion here. Well, i have separate loops for event, and other processing. And we discussed that each loop will be treated as a separate thread, as in your case, Dr Damien.
But in my case there is a little (or big) difference. I have all these separate loops (for event structure, datasocket reading, data processing etc.) inside a "state" of one big loop. so basically I have a big parent loop, and inside that parent loop, there are smaller loops.
How would that be processed? On separate processors (if my system has) , or say, as separate threads or all in one processor and a single big thread? Since the multiple loops are not completely independent, but part of a single parent loop, I am now doubtful about all the loops being treated as separate threads. In that case, I would not be enjoying the benefits of multi-threading. I would need to eliminate that outer "parent" loop in order to make the inner loops independent.
Or will the inner loops be assigned separate processor/threads?
09-28-2009 08:14 AM
LabVIEW should be smart enough to use different threads for the different loops, even if inside a master loop. As with all things LabVIEW and multi-threaded, if it really matters you should verify it is working as you expect it to. If you are working in LabVIEW 8.6 or above, you can use the Desktop Execution Trace Toolkit (an addon to LabVIEW, not free, but evaluation available). If you are working on Windows, you may be able to use one of the SysInternals tools to get some of this information. It may be somewhat difficult to get what you want this way, and I have never tried it, so do not know if it is even possible. Or you could try running the attached VI (written in LV7.1.1) on a dual core or hyperthreaded machine. It if maxes out CPU usage on both cores, threading is as expected.
09-28-2009 10:53 AM
Thanks for the reply!
We do not have Desktop Execution Trace toolkit. So I tried to use one of the Sysinternals utilities (thanks for that, didn't know about this), and downloaded Process Monitor. Among the thousands of lines, in AutoScroll mode I see two lines added whenever I Run your vi. But they have the same PID and TID. Meaning, there was only 1 thread for "LabVIEW.exe". If I run another VI, it shows another TID but not many TIDs (starting at the same moment when I Run a VI).
Sounds like there is single Thread for the vi. Earlier, looking at these many threads (for each of the window's simple task), I thought the VI might have multiple threads as well, but it refers to an instance of LabVIEW.exe only (for each new program started).
On the page of Desktop Execution Trace toolkit, I couldn't find the download link. The link to Evaluation Software refers to LabVIEW evaluation software DVD, and not the toolkit in question. the other links refer to documentation, but not the download.
PS: Since this is about the LabVIEW's internal behaviour, I thought it would be appropriate to ask someone from NI itself.
09-29-2009 07:55 AM
09-29-2009 05:32 PM
No problem.
We have LabVIEW 8.6 Academic License and on the brochure in the DVD pack I see Execution Trace Toolkit under the "Control and Embedded Systems Option Components" DVD. Didn't install while installing the system, so didn't have it on computer (searching in help didn't help either).
Ok, now I have installed, but it is installed as "Real-time Execution Trace Toolkit" (in the selection list for installation, it didn't say Real-Time), so I hope it is the same as Execution Trace toolkit.
However I don't see the VIs on the functions palette, as is shown in the help.
Also, do I have to keep the tracing VIs in my program to see the execution? Isn't it something that shows (like monitoring) the current threads of all LV processes?
09-30-2009 08:17 AM
The real-time execution trace toolkit is for debugging LabVIEW Realtime applications. It is a separate (and older) application.
The Desktop Execution Trace Toolkit is under Software Development and Deployment, the bottom tab, in the top level LabVIEW Platform DVD installer. When you get it up and running, threads are one of the columns you can show for events. This will allow you to see how many threads you are executing in.
09-30-2009 09:23 AM - edited 09-30-2009 09:31 AM
DFGray wrote:The real-time execution trace toolkit is for debugging LabVIEW Realtime applications. It is a separate (and older) application.
The Desktop Execution Trace Toolkit is under Software Development and Deployment, the bottom tab, in the top level LabVIEW Platform DVD installer. When you get it up and running, threads are one of the columns you can show for events. This will allow you to see how many threads you are executing in.
Top level LabVIEW Platform DVD? Do you mean LabVIEW Core DVD? The first DVD of the pack (for 8.6). In that DVD, in the product list, I do not see anything like "Software Development and Deployment" tab (tree node).
Following are the products that I see in the LV Core DVD:
LabVIEW 8.6
LabVIEW Control Design and Simulation Module 8.6
LabVIEW System Identification Toolkit 4.0
LabVIEW Digital Filter Design 8.6
LabVIEW Modulation Toolkit 4.1
LabVIEW SignalExpress 3.0
Circuit Design Suite 10.1 Evaluation
Vision 8.6 Development Module
Vision 8.6 Acquisition Software
Vision Builer for Automated Inspection 3.6
NI Device Drivers DVD - November 2008
There is a separate DVD (the last one in the pack) with Green color, labeled as "Extended Development Suite" which also does not have any node in its product tree list, with a name similar to "Software Development and Deployment."