Jump to content

Memory impacts of Build array growing in a while loop


Recommended Posts

Building an array with a while loop is never a good idea but I somehow am guilty of that practice and now it has come back to bite me.

I started using such a method after I read in a forum discussion that is a simple way to track changes due to a looped structure and that the "build array" block itself optimizes the memory so that the Vi does not get bogged down when run for long periods.

My state of my code says otherwise and therefore I want to know for certain how building such an array is handled in LV.

I have attached a sample VI to demonstrate what I mean. 

 

image.png.ba4086737856cc77dc241d99504b57e9.png

Growing build Array.vi

Link to comment

The answer like most things is it depends.  Are the values from one iteration loop, into the next needed for some comparison check?  Like are you going to be checking to see if a value in the array already exists from a previous iteration?  If not I would suggest wiring the output of the loop and change the tunnel to be indexing.  This has the added benefit of having the conditional input as an option which can choose which elements to have be passed out or not.

Another method that might be suggested is to preallocate the array with the initialize array function, then perform replace array element inside the loop.

The reason why building in a loop like this is discouraged, is because beginners of LabVIEW often leave this array building unchecked in size.  For simple tests that don't run long this might be just fine.  Not optimal but will work fine.  The larger problem is when this type of technique is used in a program that will run for months or years non-stop.  Memory will grow forever, and it will crash.

There is a performance hit from having to change the array size every loop which in this example will be pretty small.  If you are okay with this, and if you have a way to limit the array size some how, then I'd be fine with this type of code.  This might be something like check the array size each loop, and if it is greater than some value, get an array subset.  This can be a type of circular buffer.

Link to comment

I use this method to do a couple of things:-

1. to create a stream of historical data points (say values generated in the last 1000 iterations of the loop) and then find the highest value in that array. Data points older than 1000 iterations are not required and I would want them to get overwritten. Does this code (Fig.1) work as an alternative of what you mentioned

Quote

Another method that might be suggested is to preallocate the array with the initialize array function, then perform replace array element inside the loop.

about pre-allocation of the size of the memory that the Build Array block will use?

Since I am using a while loop here, i can not achieve this with a indexing tunnel. If (Fig.1) does not achieve this, will (Fig.2) be a good substitute?

(Fig.1):-   image.png.e9522c7154a5a31f9deeb6cb941f287a.png               (Fig.2):- image.png.58dd1a5c1f152c9c5564450f66110508.png 

2. to monitor the loop execution times in real-time rather than use the Profile>Performance and Memory tool and getting only snapshots. (Fig.3)

(Fig.3):- image.png.5c00799946c3bca143d405f3ed4b43a5.png

 

3. to check the response of hardware vs. each value generated by the For loops. This I do by having a XY-plot within the loop. (Fig.4). This is used in a For-Loop.

 

(FIg.4):- image.png.c2ecfa126aeaf20650be1dcd52ca19cd.png

Link to comment

Your Fig 1 still has a couple issues.  First the memory issue.  You build the array, then put it into a shift register that continues to build.  You need to perform the array subset, and then put that into the shift register.  Because adding elements at the start of an array were less efficient than at the end (not sure if LabVIEW improved) I often put elements at the end, then perform an Array Size, and if it is greater than some value, I use the Delete From Array, providing the index to delete as 0.  Just a pointer that probably doesn't matter.  The other issue with Figure 1 is you start with 1000 elements, then add elements one at a time.  I suspect you either want to start with an empty array, or use the replace array subset but then things like pointers and shifting might be an issue.  If you are just trying to keep it simple, I'd suggest this.  Also if you are preallocating the array with a bunch of data, doing an Array Min/Max is going to use that preallocated data too which probably isn't what you want.  If you go with a preallocated method you can still use array min max, but you will have to keep track of how full it is with real data, and then do array subset before Min/Max.  This seems easier and honestly isn't that bad.

Example_VI_BD.png.f27674906d42c8fb48cf08b6e1e371ff.png

Also you should be posting VI Snippets, these allow for posting pictures of your code as PNGs, that can then be dragged into the block diagram.  Then others can get your code more easily.

  • Thanks 1
Link to comment
50 minutes ago, Arka Dipta Das said:

1. to create a stream of historical data points (say values generated in the last 1000 iterations of the loop) and then find the highest value in that array. Data points older than 1000 iterations are not required and I would want them to get overwritten.

Just use the Array Max & Min PtByPt.vi.  It does all of this for you.  There is also the Data Queue PtByPt.vi that you might find useful.

  • Like 1
  • Thanks 1
Link to comment
27 minutes ago, hooovahh said:

Your Fig 1 still has a couple issues.  First the memory issue.  You build the array, then put it into a shift register that continues to build.  You need to perform the array subset, and then put that into the shift register.  Because adding elements at the start of an array were less efficient than at the end (not sure if LabVIEW improved) I often put elements at the end, then perform an Array Size, and if it is greater than some value, I use the Delete From Array, providing the index to delete as 0.  Just a pointer that probably doesn't matter.  The other issue with Figure 1 is you start with 1000 elements, then add elements one at a time.  I suspect you either want to start with an empty array, or use the replace array subset but then things like pointers and shifting might be an issue.  If you are just trying to keep it simple, I'd suggest this.  Also if you are preallocating the array with a bunch of data, doing an Array Min/Max is going to use that preallocated data too which probably isn't what you want.  If you go with a preallocated method you can still use array min max, but you will have to keep track of how full it is with real data, and then do array subset before Min/Max.  This seems easier and honestly isn't that bad.

Example_VI_BD.png.f27674906d42c8fb48cf08b6e1e371ff.png

Also you should be posting VI Snippets, these allow for posting pictures of your code as PNGs, that can then be dragged into the block diagram.  Then others can get your code more easily.

this implementation seems interesting. Thank you for the suggestion.

I realize now the mistake of initializing with a 1000 element array. 

I am not sure if you mean "initializing the array" when you say "preallocating the array". I was talking about memory allocation for the array rather then the initial values of the array.

VI Snippets is something I did not know about. Thank you for bringing it to my notice.

Link to comment
20 minutes ago, Arka Dipta Das said:

VI Snippets is something I did not know about. Thank you for bringing it to my notice.

They work when I save them and drag them back locally but the snippet you shared is not working. I have tried saving your snippet and then dragging it but still did not work... 

Edited by Arka Dipta Das
Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.