abhi_vt wrote:
Hi Bill and Lynn,
Thank you very much for the response. However, I am a bit confused about some of the concerns you raised. I admit that my code is not memory- and execution-efficient - possibly because I learned LabVIEW coding merely by looking at example codes. Following is my response to your comments. I would appreciate it if you could help me one more time.
"Sequence structures defeat LabVIEW's inherent parallelism. Stacked sequence structures obscure code and force right to left wiring for sequence locals. They are almost never required in good LV code, and when they are necessary it is almost always a single frame to enforce dataflow."
I needed sequence structures for initializing the digitizer. Also, some of the sequence structures were provided in the SDK of the digitizer card. What alternative do I use to Sequence Structures?
Sequence structures have limited use. They should only be used when no other method of enforcing dataflow are available. Stacked sequence structures have NO use, IMHO. They have all the disadvantages of sequence structures in general, plus they just obfuscate code because you have to figure out where things enter and exit and what frames they belong to. A state machine design pattern works better because, even though the individual frames in the case structure are hidden - as in the stacked sequence structure - wires are entering and exiting in an easily understood way.
"Local and global variables should almost never be used to pass changing data among parts of the program. They also often make extra copies of the data. Use wires, queues, or user events."
I thought local variables make the code tidy. However, it makes sense not to use them if the program makes extra copies of data.
Even though LabVIEW is a graphically-oriented programming language, never sacrifice dataflow for "neatness." Besides memory issues, global and local variable do NOT follow dataflow principles and are therefore notoriosly difficult to harness correctly.
"Value property nodes are the slowest way to move data, run in the UI thread (= slows things even more), and are rarely the best way to get access to the data."
I remember reading somewhere on this forum, that Value Property node is more efficient way than Local variables.
I read that somewhere, also. It's wrong. I think if you read further down in that topic, you would have seen that the OP had that mistaken belief based on the fact that they misread the post he was quoting.
"Nested loops have their places but in your code are likely complicating things more than they simplify them."
What alternatives should I follow?
This is a tough one. All I can say is that the more experience I gained from using LabVIEW, the less I used nested loops. I can't exacty say why, though. It just seemed that I used them less often.
"Do not dequeue from a queue in more than one place."
I have two queues in the code, which get dequeued at two locations. The third dequeue segment is disabled. I meant to delete it earlier but never got around to doing that. Do structures under "Diagram Disable" get compiled when executing the code?
Once you dequeue something, it is gone from the queue forever. It's on a first-come first-serve basis, so multiple dequeues will always be racing each other to see who gets the data and who is left out - i.e., race condition. It's likely you are missing pieces of data and you don't even know it!
[edit] I think I msunderstood this part. If you meant "two different queues with each being dequeued only once" then my advice - while still true - doesn't apply. [/edit]
Solutions:
Look at the Producer/Consumer Design Patterns. They show the best practices methods for operating loops in parallel.
I tried to follow the P/C design. The second block in the design (which contains a lot of nested loops) is the producer where the data is being acquired and the third block all the way at the bottom is where the data is being dequeued and written to the disk.
When optimizing for speed and memory usage consider these factors:
Do nothing else in the acquisition loops except the actual acquisition and enqueuing the data. All analysis and saving should be done in parallel loops with sufficient buffering (usually the queues) that the speed of those loops does not limit overall performance.
Do not do any formatting or calculations on the data in the acquisition loop.
I can revise the code to implement these suggestions.
This is perhaps the BIGGEST thig you can do to optimize your code. However, this is an optimization. This may or may not be useful in your present code and may even be detrimental or damaging with the code in its current state.
Do not display images on the front panel. This likely makes an extra copy and is certainly slow.
Although there are multiple display panels, there is only one (or two) that work. All others are disabled.
Do not configure or change parameters on the image devices while in the acquisition state.
We never actively make any changes to the configurations of the imaging devices. However I realized that the code would actually permit that activity, which implies that some CPU resources may be polling for these parameters. I will change the code to avoid this.
I look forward to your response. Thank you very much for your help, in advance.