02-15-2010 08:32 AM
Hello,
I have a beginner's question: I have a large number of variables I need to pass to a function. Will there be a difference in memory use if I pass them directly compared to if I bundle them to a cluster and pass the cluster to the function and unbundle it inside?
I tried to read online posts, and some say that cluster is like a struct... does it mean that bundling variables to cluster creates new memory locations for each variable, with overhead? My application refuses to run already ("Not enough memory") so if cluster creates new memory allocations, it's critical that I know it...
Any information is appreciated 🙂
MichalM
02-15-2010 08:34 AM
We had a discussion about this topic a few months ago.
I do not think that clustering elements will create overhead that a 'struct' would in C(or ++).
It appears that whether you decide to pass in each element individually or together as a cluster is mostly asthetic.
02-15-2010 08:39 AM
Memorology (The study of memory useage in LV) is a deep topic that can't be answered in a single post.
I suggest you check the threads linked in This Tag Cloud on that topic.
After you have read through those threads, please post any follow-up question you may have.
Trying to get you started,
Ben
02-15-2010 01:39 PM
02-16-2010 04:04 AM
Thanks to everyone...
I have already tried to read through a lot of the threads you referred me to. Trouble is I have very limited programming background, and some of the concepts there are completely new to me...
What I was looking for are general tips as to what I REALLY shouldn't do. For example, I noticed that if I do not wire arrays to a cluster, but only single-element variables, there is no new memory allocation (at least that's what Execution Trace Toolkit shows...).
As for arrays, I learned that LabView creates new copies a lot of times, but no one really knows when or how to avoid it. I try not to split wires, but still have some open questions:
1) When I split a wire so I can write the value of my array into a Value property node of an Image control - does it also create a new copy in memory?
2) I understand that shift registers are better to use than tunnels. What I thought they were for is storing a value from previous iteration for the next one, instead of taking always the original value. Is there more to shift registers, in terms of memory usage?
Thanks a lot,
MichalM
02-16-2010 04:34 AM
MichalM,
using property nodes "value" is most often a bad idea, please use the terminal to write values to indicators. Another thing is: indicators always create a new copy of the dataset, so reducing the number of indicators will reduce the amount of memory needed.
Different tunnels are always different dataspaces, so an output tunnel is creates a copy in regard to the inputtunnel. A shiftregister can address this because the left and right node grant access to the same dataspace. Please note that most often, this does not take much effect, but when working with arrays, it is mandatory to work with shiftregisters.
Norbert
02-16-2010 05:46 AM
Norbert B wrote:...
Different tunnels are always different dataspaces, so an output tunnel is creates a copy in regard to the inputtunnel. A shiftregister can address this because the left and right node grant access to the same dataspace. Please note that most often, this does not take much effect, but when working with arrays, it is mandatory to work with shiftregisters.
Hi, Norbert, you're right (as usual).
The only small thing about Shift Registers (vs AutoIndex)... Let's say, we have pretty big array (nearby memory limit), which should be computed inside of loop.
Now we have two possibilities: a) using AutoIndex tunnel, or b) using "preallocated" array and Shift Register. Something like that:
The method b) with preallocated array is "more understandable" for me also from the "traditional programming" point of view. Continuous memory allocated (like with malloc), then Shift Register acts as pointer, and we performing elements replacement step by step.
The method a) theoretically should work slow, because new elementh added to the array at each iteration (which caused memory reallocation every time), but it seems to be that LabVIEW intelligent enough for memory allocation before looping, and not during looping. And AutoIndex is faster than Shift Register in this case.
But it looks completely other with while loops:
Now array cannot be preallocated with AutoIndex, because total amount of iterations is unknown, and this caused big performance penalties (at least at first run). So, here Shift Register is preferred. What is funny - at second run the Method a) will be faster than method b) (looks like internal LabVIEW cache), but when total amount of iterations will be changed, then it will be slow again.
And finally For Loop with Conditional Terminal vs While Loop:
The total amount of iterations is unknown in both cases, but For Loop still fast because memory preallocated before iterations (created Array will be "trimmed" if loop will be breaked with condition).
It means, that sometimes (but not always) AutoIndex is more preferred than ShiftRegister.
Andrey.
02-16-2010 06:30 AM
Andrey Dmitriev wrote:
[...]
The total amount of iterations is unknown in both cases, but For Loop still fast because memory preallocated before iterations (created Array will be "trimmed" if loop will be breaked with condition).
It means, that sometimes (but not always) AutoIndex is more preferred than ShiftRegister.
Andrey.
Hi Andrey,
ok, you got me, i stated to prefer shift registers over tunnels as a general fact. I made this remark without thinking on creation of the array using autoindexing.
As Andrey showed in his examples, For Loops with Autoindexing Outputtunnels are good for creation of arrays where all elements have different values.
In all other situations, my remark is true nevertheless.....
Norbert
02-16-2010 07:09 AM
Andrey,
great presentation 🙂
Thanks for tips. I am actually working with IMAQ images (a purple wire) and not arrays, and they are big, so the shift register should be helpful (I still have tunnels in some places...).
If it works similar to pointer, than it's exactly what is needed (and what I expected, not knowing that LabView copies data so frequently...)
It may also be that my problem is elsewhere... I have a MathScript node in a subVI, and now I've read in Help texts that the subVI memory is not automatically deallocated when it finishes execution (including all subfunctions). I see that this subVI has a large memory usage, and if it's not free after it finishes the calculation, then this could be the fix I need to do. Working on it still.
Michal
02-16-2010 07:30 AM
michalm wrote:Andrey,
great presentation 🙂
Thanks for tips. I am actually working with IMAQ images (a purple wire) and not arrays, and they are big, so the shift register should be helpful (I still have tunnels in some places...).
If it works similar to pointer, than it's exactly what is needed (and what I expected, not knowing that LabView copies data so frequently...)
It may also be that my problem is elsewhere... I have a MathScript node in a subVI, and now I've read in Help texts that the subVI memory is not automatically deallocated when it finishes execution (including all subfunctions). I see that this subVI has a large memory usage, and if it's not free after it finishes the calculation, then this could be the fix I need to do. Working on it still.
IMAQ images wires ("Purples wires") are references in the fact. There are no any significant performance differences if they passed as tunnel or shift register. The only point why shift register is preferred in this case is the situation, when loop not executed (you will get "Not an Image" error after such construction):
What you can try with memory issue is following:
But here I'm not sure - I haven't any experience with MathScript as well as with function descriped above (still never used it)
Andrey.