LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Why this particular Buffer Allocation?

Solved!
Go to solution

Win Vista, LabVIEW 8.6.1, PXI 8196, LV RT 8.6.1 

  

 

I have a problem with a PXI program used to control an engine/dynamometer via PID loops according to a prescribed cycle of setpoints (specific speed/torque targets to meet).

 

The normal CPU usage (as shown on the PXI's monitor output) is normally 2%.  My loop rate is 100.000 Hz, and I've been diligent about spreading the work around, so it works very efficiently.

 

A "normal" test has been for 20 minutes, so we've never noticed a problem.  However, my client recently ran an 8-hour test, and he noticed that the CPU usage would creep up and up during the test, to where it was 75% at the end of 8 hours.

 

I ran my own 2-hour test and observed the same thing - the CPU Usage crept up to 20%.

 

In tracking things down, I noticed it's correlated to the size of an array of setpoints in the PXI controller: The bigger that array, the more CPU usage.  During the test, the setpoints are set over from the host just ahead of time, so the array slowly gets bigger as the test goes along.

 

When the test is over, the array does not disappear, and neither does the CPU usage.  I can go all the way through starting a new test, and the CPU usage drops when I send a command to flush this array.  Therefore, I'm certain that the size of the array is the problem.

 

A two-hour test contains 120 x 60 x 10 = 72000 setpoints (Setpoints from the host are at 10Hz,  100 Hz setpoints are interpolated on the controller) At 24 bytes each, that's 1.728 Mbytes.  NOT a huge RAM hit (2 Gigabytes available).

 

I couldn't picture why the existence of this big array would take CPU time, but the evidence is staring me in the face: the bigger the array, the more CPU used.

 

In looking for an answer, I turned on the BUFFER ALLOCATIONS view, and found a place where LV is making a COPY of this buffer, and I don't understand why.

But that would explain things: copying a 1.7 MByte array at 100Hz will certainly put a burden on the CPU.

 

So here's the code: In the TRANSIENT state, the array is used to pick out and interpolate the next setpoint.

 

Buffer1.PNG 

 

 

When the test is over, we go to the RAMPDOWN state, where the array is not even used: 

 

Buffer2.PNG 

 

After that, we're in IDLING state, where again, the big array is not used. 

 

Buffer3.PNG

 

 

So, before I re-architect things to eliminate the old setpoints (I have lots of issues with accounting), can anyone explain WHY the indicated buffer allocation occurs?

 

Note that I show the "0" case, the other case is "default" which handles the other 9 out of 10 cases.  But there's a buffer allocation even there, when the array is not  even connected inside.

 

More importantly, can I avoid this allocation? 

Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


LinkedIn

Blog for (mostly LabVIEW) programmers: Tips And Tricks

0 Kudos
Message 1 of 23
(3,744 Views)

Isnt the size of that buffer read in every case struscture then compared against a numeric to ultimately give a Boolean Output.  Thus it is used in every case structure you have shown as LabVIEW re-examines it in every case as it doent know its a constant.

 

Educated guess, may be worth a quic recode tosee if it solves the problem.

 

EDIT

Looking at it again i think you need to show the other cases from the outer case structure, as that is where the buffer copy is occuring. 

 

 

Message Edited by craigc on 10-14-2009 08:47 AM
LabVIEW 2012
0 Kudos
Message 2 of 23
(3,739 Views)

Isnt the size of that buffer read in every case struscture then compared against a numeric to ultimately give a Boolean Output.  Thus it is used in every case structure you have shown as LabVIEW re-examines it in every case as it doent know its a constant.

 

Yes, it is used for that, but it shouldn't need to make a COPY of it just to find out the length. 

 

 Educated guess, may be worth a quic recode tosee if it solves the problem.

 
Don't know what you would have me re-code.  Finding the length should not require a copy.
 
 
Looking at it again i think you need to show the other cases from the outer case structure, as that is where the buffer copy is occuring.  
 
 
The "0" case handles setting a new setpoint, the only other case is "Default" which does nothing (the setpoints are interpolated for that).  But even here, it appears to be making a copy, A fact that I don't understand.
 
Buffer4.PNG 
Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


LinkedIn

Blog for (mostly LabVIEW) programmers: Tips And Tricks

0 Kudos
Message 3 of 23
(3,728 Views)
Solution
Accepted by topic author CoastalMaineBird

It is hard to say without poking at it but I have seen similar patterns result in an extra buffer copy.

 

1) (Least probable) The wire forking to feed the array size is confusing LV and it thinks it needs another copy. I saw this in about LV 7.1 and may not apply with LV 8.6.1.

 

2) The sub-VI  "used to pick out and interpolate the next setpoint" does NOT have the control on the icon connector on the "root" of the diagram and or the data is not wired through. To understand what I am getting at please refer to the "Clear as Mud" thread where Grg McKaskle was called out of retirement to explain how sub-VI's can work in the buffer of the caller (this is really what you want to happen in the code you showed us).

 

Reader's Digest Version:

 

When LV "sees" data be passed into and out of a sub-VI and there are no operations that will modify the contents of the data, the data will be passed by reference so the sub-VI will do its work in the callers buffer.

 

This code image shows the difference.

 

 

Ben

 

 

PS "Buffer Allocation" in the tilte gets my attention.

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
Message 4 of 23
(3,724 Views)
Well the array size function is in all your case's so to be pedantic it should be done outside of the case strusture.  Inside it is just bloating your code and still may be the source of the buffer allocation.  Apart from that its the only thing i can think of.  Have you tried to turn on constant folding?  If the bundle is not a constant then LV will re-evaluate it within each case 🙂
LabVIEW 2012
0 Kudos
Message 5 of 23
(3,723 Views)

Oh and Ben has prob hit the nail on the head.  I went through that sometime ago and have forgot about putting controls inside the case structure of sub VI's I put them on the outside as matter of fact now.

 

I also got told of about 6 months ago for having duplicate code inside case structures 🙂  Putting them on the outside makes it easier to read too imo.

 

And i have noticed you havent got the same array size function in there anyway so apologies for that .:( coffee time i think!

Message Edited by craigc on 10-14-2009 09:10 AM
LabVIEW 2012
0 Kudos
Message 6 of 23
(3,719 Views)

I verified that there is NO possible path through the code where the array gets modified after this unnecessary copy operation.

 

 

Hmmm.  If I break the wire (indicated in blue) carrying this array to the inner case, it STILL makes a copy, even though the ONLY connection to the array is to the ARRAY LENGTH function.

 

Why does it need to make a copy just to find out it's length?

 

Buffer5.PNG 

Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


LinkedIn

Blog for (mostly LabVIEW) programmers: Tips And Tricks

0 Kudos
Message 7 of 23
(3,715 Views)
I suspect that you can solve this, or at least narrow it down further, by having the setpoint array pass through the case structure and back out to the shift register, rather than forking the wire at the top.  My guess would be that there's something inside Transient Setpoint Manager that causes the copy, and that if any one case in a case structure requires a copy then LabVIEW makes a copy for all cases (I can imagine that this simplifies memory management if it's not dependent on which case in the case structure is selected).
0 Kudos
Message 8 of 23
(3,712 Views)

Thanks, Sir Ben  ;->

 

The wire forking to feed the array size is confusing LV and it thinks it needs another copy. I saw this in about LV 7.1 and may not apply with LV 8.6.1. 

 

Given that I removed the OTHER fork (see above pic) and left ONLY the ARRAY LENGTH function and it STILL made a buffer allocation, I'm raising the odds in favor of LV confusion.

 

 

 The sub-VI  "used to pick out and interpolate the next setpoint" does NOT have the control on the icon connector on the "root" of the diagram and or the data is not wired through.

 

--- Well, the data is not wired thru, because it does not need to be.  It's never modified within this section.

 

As far as the subVI not having it's terminal on the root level of the diagram, well, that's not the case:

 

Buffer6.PNG 

 

However, the array is passed on to a further sub-subVI, and in THAT case, it is NOT on the root level:

Buffer7.PNG 

 

I will move that and see what happens.

 

I don't understand it though.  In no case could the array possibly be modified. 

 

Message Edited by CoastalMaineBird on 10-14-2009 09:23 AM
Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


LinkedIn

Blog for (mostly LabVIEW) programmers: Tips And Tricks

0 Kudos
Message 9 of 23
(3,691 Views)

CoastalMaineBird wrote:

Thanks, Sir Ben  ;->

 

...

 

 

I will move that and see what happens.

 

I don't understand it though.  In no case could the array possibly be modified. 

 

Message Edited by CoastalMaineBird on 10-14-2009 09:23 AM

Greg McKaskle is/was there at the meeting when the details of "in-placeness" were being worked out. He explained thing in the Clear as Mud Thread. LabVIEW can recognize the "wired-through on the root" code pattern as "data not modified".

 

If simply doing the wire through to that sub-VI and its sub-VI is not enough to get the in-placeness to change its mind, follow through waht I think I heard Nathand say when he suggested wire the data through all of the casses of the case structure with the extra allocation.

 

I do appreciate updates since this is how we stay up on this important but subtle topic.

 

Ben

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
0 Kudos
Message 10 of 23
(3,678 Views)