LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Memory saving

Hi to all. Labview copies variables in every access time to it. How to control that?

How to make an array and get it's any value prevent copy all array in new memory cell?

Red circles is new cells of the same array. It shows in tools\profile\shows buffer allocations menu.

And What is differense in left and right variants?

 

 

0Forest0_1-1579891737141.png

0 Kudos
Message 1 of 9
(3,527 Views)

It would help to see some actual code.

 

I am not sure why you think you need to run these loops as fast as the computer allows, it also does not make a lot of sense to read the same global twice in parallel. Reading from a global needs to make a datacopy to do local operations, but if the array size does not change it can of course re-use the same buffer. The shown code cannot know if the size changes, so it needs to check if a new memory allocation is needed or not whenever the global is read.

 

Why is the global even an array, since you only ever look at one element?

 

Instead of a global, you could use an action engine which keeps the array in a shift register and only takes a few scalar inputs/output (index, value, operation (init, read, write, etc.).

 

Do you have performance problems? (If so, they are most likely caused by all these greedy loops). Are you trying to solve a particular problem? How does this code fit in the rest of your project?

Message 2 of 9
(3,459 Views)

@0Forest0 wrote:

 

Red circles is new cells of the same array. It shows in tools\profile\shows buffer allocations menu.


This is not always true; it shows where there may be a buffer allocation. You can use the Tool "Profile Buffer Allocations" to see where there are real buffer allocations while your program is running.

 

mcduff

Message 3 of 9
(3,433 Views)

As another member has rightly pointed out using an action engine that utilizes shift registers, but I feel using an action engine in two parallel loops might cause synchronization issues, and I will recommend using those when the data flow is secured.

 

Coming to your requests, data value references(DVR) is a better way of dealing big data sets which otherwise might take a big chunk from your RAM because they don't copy the value but the reference like a pointer does inn C++, even I can suggest a more optimized way of converting data into the variant type and then into a DVR and while retrieving data back do the opposite. However, even if this can save a lot of RAM space but due to data conversion, it can take a little more time. I guess you need to do the trade-off.

 

Using a global variable for large data is not recommended(however there might be some exceptions).

 

More on DVR: https://devs.wiresmithtech.com/blog/by-value-vs-by-reference-in-labview/

Message 4 of 9
(3,262 Views)

@Abhi_95 wrote:

As another member has rightly pointed out using an action engine that utilizes shift registers, but I feel using an action engine in two parallel loops might cause synchronization issues, and I will recommend using those when the data flow is secured.


You'll get similar synchronization issues with a FGV as with a DVR solution.

 

With the DVR, you can make several functions in different VIs, with the FGV it will always come down to calling the one VI. So if you have lengthy actions and fast actions, a DVR might be preferable...

 

A FGV will secure flow though, in the same way a DVR will. Both still allow race conditions, for instance when you read, change and write outside the DVR\FGV...

 

Another plus for DVRs (over globals) is While DVRs are by reference, at least they are by wire. So if you at some point want to reuse the code In a 2nd instance, you can with a DVR. While a global will be global over those two instances.

 


@Abhi_95 wrote:

 

Coming to your requests, data value references(DVR) is a better way of dealing big data sets which otherwise might take a big chunk from your RAM because they don't copy the value but the reference like a pointer does inn C++, even I can suggest a more optimized way of converting data into the variant type and then into a DVR and while retrieving data back do the opposite. However, even if this can save a lot of RAM space but due to data conversion, it can take a little more time. I guess you need to do the trade-off.

A variant type as a more optimized way? If you want speed and low memory overhead, don't use variants...

 

You'll always have comfort\memory usage\execution speed as tradeoffs.

 

How do you know you need to optimize in the first place?

 


@Abhi_95 wrote:

Using a global variable for large data is not recommended(however there might be some exceptions).

 

More on DVR: https://devs.wiresmithtech.com/blog/by-value-vs-by-reference-in-labview/


I'd also avoid DVRs, and usually succeed.

 

DVRs are a problem when it comes to debugging. Once the top level VI of the VI that created the DVR stops running (e.g. when stopping the code to debug) the DVR dies with it. So, no more debugging...

 

But the solution is not in the details of synchronizing the data, but in avoiding the need for it... It will be hard to recommend anything without a complete picture.

Message 5 of 9
(3,110 Views)

@Abhi_95 wrote:

As another member has rightly pointed out using an action engine that utilizes shift registers, but I feel using an action engine in two parallel loops might cause synchronization issues, and I will recommend using those when the data flow is secured.


Generally (as in, basically always when referring to "Action Engines") the VI is marked as non-reentrant. This, combined with the use of "atomic" operations, prevents synchronisation issues.

 

Spoiler
If you don't have multiple actions, you can use preallocated reentrant Uninitialized Shift Registers as a storage device, but each location that calls it will have a separate copy and so separate data. As a result, you can't get the data out from somewhere else, or do multiple actions easily (because you'd usually want multiple callers for that).

The problem you describe happens when you do something like "Read", make changes in your calling VI, then "Write", because you can't guarantee that the data in the AE/FGV hasn't changed since you read it.

 

To avoid this, you'd generally want to implement an additional method in the Action Engine (this is what distinguishes them from FGVs (Functional Global Variables)). If your action in the caller was for example to use Build Array set to Concatenate Inputs to make your array longer, you could implement an "Append" action instead of using "Read" then "Write".

 


@Abhi_95 wrote:

Coming to your requests, data value references(DVR) is a better way of dealing big data sets which otherwise might take a big chunk from your RAM because they don't copy the value but the reference like a pointer does inn C++, even I can suggest a more optimized way of converting data into the variant type and then into a DVR and while retrieving data back do the opposite. However, even if this can save a lot of RAM space but due to data conversion, it can take a little more time. I guess you need to do the trade-off.


I'm not sure what you mean by this. If conversion to a Variant saves space in some way, it can almost only be because it's losing information.

For example, converting a DBL to a string with fewer than 8 characters will save space, but DBLs typically require more than 8 characters to store the same level of precision (~16 significant figures).

A counter example might be storing the value 4 as a string rather than a DBL, conceivably this takes you from 8 bytes to 1 byte, but it becomes much harder to use as a number.

However, if you convert back to numbers to process your Variant, you'll be back at the original size (possibly with a loss of precision). Why is this more optimised?


GCentral
Message 6 of 9
(3,106 Views)

@cbutcher wrote:

I'm not sure what you mean by this. If conversion to a Variant saves space in some way, it can almost only be because it's losing information.

For example, converting a DBL to a string with fewer than 8 characters will save space, but DBLs typically require more than 8 characters to store the same level of precision (~16 significant figures).


Sounds like you are confusing Variants with ASCII strings.  Variants will store the binary data in it.  So a DBL in a variant will still be 8 bytes (plus some overhead for the variant).

 

In regards to race conditions, here is an example I put together several years ago: A Look At Race Conditions


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
Message 7 of 9
(3,094 Views)

Thanks for all. That code is not finished code or part of something else. That is just thoughts of way to use array of data. The goal is use one array with many properties or settings and one cycle is writer for others readers. If you are change any index of the array, all readers have to see that.

0 Kudos
Message 8 of 9
(2,991 Views)

@crossrulz wrote:

@cbutcher wrote:

I'm not sure what you mean by this. If conversion to a Variant saves space in some way, it can almost only be because it's losing information.

For example, converting a DBL to a string with fewer than 8 characters will save space, but DBLs typically require more than 8 characters to store the same level of precision (~16 significant figures).


Sounds like you are confusing Variants with ASCII strings.  Variants will store the binary data in it.  So a DBL in a variant will still be 8 bytes (plus some overhead for the variant).

 

In regards to race conditions, here is an example I put together several years ago: A Look At Race Conditions


Sorry, perhaps I was unclear. I meant that generally, for something to take up less space (excluding compression setups) it must contain less information.

Then I gave an (unrelated to Variants) example that countered this, but only in special/specific cases, e.g. short integer values stored as doubles can be larger than their equivalent string (not variant) representation.

 

As you commented above, the variant with double is larger than just the double (hence my confusion with the post I quoted, in which variants were given as a way to reduce memory usage - I didn't/don't see how this would work).


GCentral
0 Kudos
Message 9 of 9
(2,983 Views)