From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Array Preallocation and Memory Management

I inherited some RT code that makes liberal use of the Build Array function--even in time critical loops--which I know is a no-no. I am looking into ways in which I can remove those jitter-inducing function calls while still maintaining the original design pattern. What I would like to do is preallocate the arrays to the maximum size and then replace subsets of the arrays as needed. The problem is, I need to read from the arrays periodically, and I need to be able to step through the elements using an auto-indexing For loop, so I don't want dummy data causing unnecessary iterations/calculations.

 

My initial idea was to preallocate an array to the maximum size I would need, then immediately delete the contents and begin rebuilding it using the Replace Array Subset function. However, if that even works (to be honest, I haven't even tried it yet), I figure the most that will buy me is some contiguous memory space to work with (to avoid fragmentation), but I imagine I will still be invoking the memory manager, and thus still introducing jitter each time I add data back into the array. Can anyone comment on that? Am I right? Or horribly, horribly wrong? Robot wink

 

I also thought about trying to use the new Lossy Queue available in 8.6 to create a circular buffer, but that doesn't help me with utilizing the auto-indexing feature of For loops, since I would still have some dummy data in it.

 

Can anyone offer any suggestions as to another way I might handle this situation?

Message 1 of 17
(6,394 Views)

Do the pre-allocate and then use replace array sub-set so the buffers stays at fixed size. Don't clear the buffer because that will put the buffer back in the pool for use elsewhere.

 

Still use your for loop but wire the iteratin terminal with the actual count of valid elements in your array while still using the indexing terminal to step through the array.

 

Ben

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
Message 2 of 17
(6,389 Views)
Why do you have to autoindex the array? You can preallocate the array, then when you have "filled" it with valid data you should know how many elements that is and pass that value to the For loop's interation N, indexing the array inside the loop.
Putnam
Certified LabVIEW Developer

Senior Test Engineer North Shore Technology, Inc.
Currently using LV 2012-LabVIEW 2018, RT8.5


LabVIEW Champion



0 Kudos
Message 3 of 17
(6,388 Views)
Ben types faster than I do!
Putnam
Certified LabVIEW Developer

Senior Test Engineer North Shore Technology, Inc.
Currently using LV 2012-LabVIEW 2018, RT8.5


LabVIEW Champion



0 Kudos
Message 4 of 17
(6,386 Views)

LV_Pro wrote:
Ben types faster than I do!

 

"We don't need no stinking spell checker" Smiley Tongue

 

Ben

 

PS you may also want to review these tags and the related tags where I have collected a bunch of threads that talk about performance.

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
Message 5 of 17
(6,380 Views)
Well, if you must use the auto indexing, you'd always have to get the exact
data size from the buffer. Therefor, LVRT will always make a copy of the
data, and that would defy the entire purpose.

You really don't (*ever*) need the auto indexing. You can always use an
array size function, and an array index function to do the exact same thing.

So, make a buffer for each array. Make it maximum size (you can make it
growable, but that will induce jitter, although you can grow it at
convenient times). The buffer should have an init function, an add function,
a get function and get size function (perhaps a get range function). In a
for loop, add with the add function. In stead of using the auto indexing,
use the get size and get functions.

Hope it helps. I'm not sure I'm getting your problem.

Regards,

Wiebe.


0 Kudos
Message 6 of 17
(6,356 Views)

Reviving this old thread. I need some tribal knowledge.

I have a cRIO system, developed in LV2011 that is crashing - apparently running out of memory. Using the VI analyzer tool kit on similar VIs in a LV2013 project, I discovered some bad practices that I must blame myself for. Chief culprit right now is the 'Arrays and Strings in Loops' error. According to the result window, the analyzer does not check for this condition within timed loops, of which I have plenty.

 

BuidArrayNoNo.png

 

I am currently running the vi profiler to hopefully get quantification before and after I fix the remaining build arrays within while loop issues that I have - the above snippet shows 30 cases alone (each case is pretty much identical excepting the variables being 'packed').

 

So, in fixing the others that the analyzer found I ended up using a Bundle and then a cluster to array. (This example is not Booleans being packed into a word but presented to show how I eliminated at least one of the 'Array and String in Loops' error from the vi analyzer tool kit).

ClusterToArray.png

 

The input array is pre-allocated outside of the while loop. And I only have this situation packing the Booleans outbound in the Modbus array(s). Packing the words, I use no build array function, rather the replace array subset.

 

Questions

1) Is this a valid way to replace the build array?

2) What would be better?

3) On my LV2011 machine I do not see an option for running the VI Analyzer, was it available then? Or did I simply not install it.

 

 

 

0 Kudos
Message 7 of 17
(4,689 Views)

Why not expand the Replace array and wire all booleans directly? The Cluster to Array must be way worse than the other option.

/Y

G# - Award winning reference based OOP for LV, for free! - Qestit VIPM GitHub

Qestit Systems
Certified-LabVIEW-Developer
0 Kudos
Message 8 of 17
(4,679 Views)

The array is U16. How would I wire booleans to it?

   

     "The base data type of the new element or subarray must be the same type as the input array."

 

0 Kudos
Message 9 of 17
(4,675 Views)

Insert a bool to 0,1 in between 🙂

(This also adds to the suggestion of booleans coercing to 0,1 if connected to numeric functions)

You could also optimize by using the build array and bool array to number, in which case they'll be bits/flags in a single U16. (requires some redesign though)

/Y

G# - Award winning reference based OOP for LV, for free! - Qestit VIPM GitHub

Qestit Systems
Certified-LabVIEW-Developer
0 Kudos
Message 10 of 17
(4,670 Views)