03-13-2024 07:40 AM
In a VI, a subarray is created from an existing array. This subarray is accessed read-only.
The LabVIEW compiler creates a copy in memory for the subarray, although only read access is made to the subarray of the main array.
With multiple read accesses, this generates increased memory and CPU requirements.
More memory is not the problem, but the load on the CPU cores due to the many copy operations is a waste of performance.
I tried to work with DVR as well, but as soon as I create a subarray from my main array to read on this data, the LabVIEW Compiler uses another chunk of memory for this.
In my use case, I do not read the data for real, this is only for the example.
But I need to put a chunk of the “main”-array into an FFT or other functions.
And the extra memory usage only to put a part of the “main”-array into a specific function seems like a waste of memory.
As mentioned, the extra memory usage is not the thing that bothers me, but we need to put pieces of the main-array into other functions several times. The constant copy of data increases the CPU load and makes the code less effective.
Is there a better way to access a part of an array without copying that part every time?
Happy to correspond with anybody about this.
Solved! Go to Solution.
03-13-2024 09:19 AM - edited 03-13-2024 09:25 AM
Hi,
How can you be sure a copy is created in memory?
I would advise you to try using the Desktop Execution Trace Toolkit to see buffer allocations.
From my experience, the LabVIEW compiler can sometimes optimize buffer allocations in rather simple cases, but as soon as your sub-array goes through several structure tunnels, it usually creates a copy to ensure safe access. So if you want to avoid that, you should try to put your operation on the sub-array (FFT, ...) as close as possible from the "Array Subset" function, and use inlining on subVIs that access the array. Also, you should avoid accessing the sub-array in nested structures as much as possible.
Regards,
Raphaël.
03-13-2024 10:28 AM
For more details on subarrays, give this thread on LAVA a good read: https://lavag.org/topic/7307-another-reason-why-copy-dots-is-a-bad-name-for-buffer-allocations/
03-13-2024 10:35 AM
Where do you think there are unneccessary copies being made here?
03-13-2024 11:41 AM - edited 03-13-2024 11:54 AM
I really don't understand what problem you are trying to solve. And putting "bug" in the filename is way too suggestive unless you have identified it as a real bug.
What's the point of the sequence frame? Are you aware that in the DVR example, you are mixing references and if you stop the while loop, you are trying to close the same reference twice. You are creating up to three DVRs, but only ever close one of them.
If you need to do an FFT on a subarray, a copy simply needs to be made. No way around it. The FFT is a dll that definitely needs it's own sandbox. Many other primitives need clean inputs. (Yes, of course you could create your own FFT from scratch that operates on a subset of data in place, but it will be orders or magnitude slower and you still need to allocate the same amount of data for the output.)
Can you modify the example to show a more realistic use?
Note that the compiler will always try avoid memory copies (for example a transpose or reverse might just mark it as remapped indices instead of moving elements in memory. (... but that can cause other performance problems, a different topic). The context help when hovering over a wire will tell you if the array is just marked as having modified indices. In your case, the subarray is only created at the output tunnel of the case structure. Before that, the context help shows it as "(sub)array", which means exactly that.
03-21-2024 03:38 AM
Hi,
Thanks to all of you for your help and your hints.
So the conclusion is that as long as I keep my array and subarray data within the loop, the LabVIEW Compiler can minimise the memory usage. But as soon as I leave the loop or case structure, a copy in memory is made.
I will surely check on this if the code can be optimised in that way.
To be honest, it is not my code and the code I have to work with is real spaghetti-code at its best.