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 functional global uses 2x the initialized space?

Solved!
Go to solution

I had a thread going about how to reduce memory allocation on our LabView RT system located here for reference http://forums.ni.com/ni/board/message?board.id=170&thread.id=413552 .

 

I am using a functional global/Action Engine to append to a U32 array that I get back from our PXI FPGA cards via DMA reads.  In order to retain determinism, this array is first initialized via the AE to its maximum size (18Million).  During my debugging process, I decided to run the "Performance and Memory" tool.  When I set the number of elements to initialize to 18,000,000 I would expect the performance tool to show me that this VI takes up 18,000,000 * 4bytes = 72Mbyte.  However, after running this VI and clicking the snapshot button I see this VI take up 144Mbyte, extactly twice as much!

 

I next ran the "Show buffer allocations" tool and with "Arrays" checked, I see a black dot on the Initialize Array primitive as well as a black dot on the left-most shift register.  Clicking on the 'help' button in that tool I see it say under the array section "avoid overusing global and local variables when working with arrays. Reading a global or local variable causes LabVIEW to generate a copy of the data."  This has got to be what is going on, but how else am I supposed to store this data with the flexibility of an AE and not have an extra copy floating around? 

 

Below is the pertient part of the AE for your reference:

 

clear2.png.png


Message 1 of 6
(3,703 Views)

Here is the VI in question:


Message 2 of 6
(3,701 Views)
Solution
Accepted by topic author SeanDonner

Hi there

 

When you use the "Initialize Array" function you create an additional array. Use the "Reshape Array" function instead to reuse the already existing array. See attachment.

Best regards
chris

CL(A)Dly bending G-Force with LabVIEW

famous last words: "oh my god, it is full of stars!"
Message 3 of 6
(3,679 Views)

A few more comments:

 

  • Array subset seems to be a more appropriate tool than split array in this context. Why the odd choice?
  • You should place all terminals outside any structures (see this discussion)..
  • If you would upgrade your LabVIEW version, you would no longer need the while loop at all. The new feedback nodes no longer need to be tied to a loop.
Message 4 of 6
(3,660 Views)

chrisger wrote:

Hi there

 

When you use the "Initialize Array" function you create an additional array. Use the "Reshape Array" function instead to reuse the already existing array. See attachment.


Wow, that is not a very intuitive result.  I've taken both the Basic and Intermediate LabVIEW courses which both recommend the Functional Global and never did they ever mention that you would be creating 2x copies of your data when you Initialize your array; which would seem to be the logical choice over "Reshape Array."  I'm glad the fix is so easy but can one of you explain the nuts and bolts behind why this happens?

 


  • Array subset seems to be a more appropriate tool than split array in this context. Why the odd choice?
  • You should place all terminals outside any structures (see this discussion)..
  • If you would upgrade your LabVIEW version, you would no longer need the while loop at all. The new feedback nodes no longer need to be tied to a loop.

I chose 'Split Array' because it is index-based whereas 'Array Subset' is length based.  Using 'Array Subset' for the same functionality would require me to add one to the running index count.  Not really a big deal.  This operation only happens once per test so the performance difference (if any) to go with 'Split Array' seemed negligible.

 

Thanks for the article on where best to place terminals, I do tend to place them outside but never really made a strict habit out of it since I never really heard anybody address if it mattered either way.  Now that I know, I will make a concerted effort to always make the terminals on the root of the VI.

 

As for upgrading, I'd love to stay bleeding edge but unfortunately Mill-Aero makes that pretty impossible; we are locked in at 8.2 for this project.  Feedback nodes without loops are less intutitive to me anyway, although I'm sure that just comes from my comfort and familiarity of doing it that way for so long.

 


0 Kudos
Message 5 of 6
(3,633 Views)

Hi there

 

".. which both recommend the Functional Global and never did they ever mention that you would be creating 2x copies of your data when you Initialize your array.."

 

 

This is not a matter of the FGV. FGVs ARE the weapon of choice in most use cases (other opinions may differ, but that's a different question). When dealing with BLOBs (arrays, images, strings etc.) or with applications on a RT platform you should avoid to create duplicates of BLOBs or addiotional BLOBs. In your case with the "Initialize Array" function there are TWO arrays, there prior array containing the data and the new initialized clean Array -> twice the amount of memory needed to store both arrays, because the clean array does NOT use the memory of the old data array. The "Reshape Array" function uses the already existing memory of the old array for the new one and adapts the size if required. In case that the new array is larger than the old one only the additional memory will be allocated.

 

"..Array subset seems to be a more appropriate tool than split array in this context..."

 

"Split Array" creates two new arrays and deletes the old one, while "Array subset" creates only ONE new array (the subset), but keeps the original array unchanged in memory. Changing sizes or number of BLOBs invokes the "memory manager" of the RTE. The memory manager is a shared ressource, because changes in memory are handled in serial, so the timing behaviour of RT-applications may be disturbed. This is why you always should reuse existing memory instead of free and allocate new one.

 

I think there's a chapter in the real time module manual that describes this a bit more in detail. 

Best regards
chris

CL(A)Dly bending G-Force with LabVIEW

famous last words: "oh my god, it is full of stars!"
Message 6 of 6
(3,612 Views)