LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Computing Time of large Arrays

Solved!
Go to solution

Dear Friends, dear LabVIEW developers,

I'm trying to reduce computing time for large arrays. (In real life I'm eliminating unimportant vertexes of a 3D-mesh.)

Migrating from 8.6 to 2011 already has done a great job for me. And also I'm happy to run Windows 7 on a 64-Bit machine.

But, imagine a pointer orientated language where you would change one array element, you wouldn't expect the computing time to change with the actual length of said array.

Here I'm working actually on a large array of clusters of possibly different length array (rather short ones, containing the indexes of my vertex's neighbors).

My problem is that I really can't see the reason for (neither am I happy about) the 100 times slower performance when having a 100 times larger array at hand for just exchanging on elements value.

Any suggestions for work-arounds to get the speed of large arrays comparable to small ones is highly appreciated.

Kind regards

  Jannis

PS: I tried DataValueReferences but just the computing time to get 1Million references nears an hour.

ArrayComputingTimes.png

0 Kudos
Message 1 of 10
(4,144 Views)

Hello,

 

  I am far from the most experienced person when it comes to LabView performance analysis, but I thought I'd give a shot at replicating your sample code.  What caught my attention was the use of tunnels in the For Loop.  I'm really not sure how LabView handles the memory for these, but it apparently has an interesting interaction with the In-place Element Structure.  I tried replacing the array tunnels in the loop with Shift Registers and the performance different was enormous.  Not only did the entire process run faster, there was no significant difference between the larger and smaller input arrays.

 

  It's possible this isn't relevant to your end application outside of the sample code, but I thought I'd throw that out there for consideration.

 

Best wishes,

Steven I


Steven I
Message 2 of 10
(4,126 Views)

try using Tool Profile >>> Show buffer allocations to get another clue.

 

I suspect the contruct used to develop the large array spits out a buffer but since the code want to modify it and the buffer should be the same for evry iteration, LV has to duplcate it.

 

If using a Shift register, you are telling LV it is OK to modify the buffer so the allocation happens only once.

 

But I am just throwing out ideas to try and help,

 

Ben

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

Hi Steven , hi Ben, thanks for your interest,

yes ist seems you're on to something there. Maybe I'm chasing a phantom here - as so often! Of course I'm using the "Show Buffer Allocation" a lot, but it seems I missed it this time. Looks like I have to change the way I do the bench marks. Cause, you can trust me, the real world application shows just this effect (otherwise I wouldn't be doing this) and I'm trying to home in on the "time hole".

I'll keep you posted once I checked the other "suspects".

Jannis

Unbenannt.png

0 Kudos
Message 4 of 10
(4,107 Views)

To avoid folding, convert your cluster input to a control. Also convert the number wired to N to a control. 

 

Of course using the "in place element structure" does not give you any advantage if you change the size of an array deep inside your structure. Since the size changes, it cannot be done in-place. Right?

 

If performance in important, stick to structures with a fixed size.

 

EDIT: Ah, sorry, you are actually keeping the size constant, just in a convoluted way.

Message 5 of 10
(4,101 Views)

I'm honored to receive a reply by THE altenbach, thank you!

Since the idea is to reduce the size of the large vertex array, sticking to a fixed size is not an option. Right?

Hope was, that the small "neighbours" arrays would reduce their size easier than the whole vertex array. But has LV really joined all those little arrays inside their clusters one after the other to create the large array? Give me my pointers back!

And please, what is folding? Does it matter outside my little demo bench mark VI?

Jannis

EDIT: Yes I was keeping the size constant, but not in real world. And the bench mark had the flaw pointed out by Steven and Ben

0 Kudos
Message 6 of 10
(4,091 Views)

@Jannis wrote:

I'm honored to receive a reply by THE altenbach, thank you!

Since the idea is to reduce the size of the large vertex array, sticking to a fixed size is not an option. Right?


Wrong!  to keep this a fixed size for best performance just move the element to delete to the end of the array, Count how many times you did this in the loop ("R") and remove them all at once after the loop with Delete from array ("R).  1 buffer realocation. 


"Should be" isn't "Is" -Jay
Message 7 of 10
(4,083 Views)

Jeff,

Yep! Already doing this - for the vertex array that is not part of my example here.

Trouble is: with every deleted vertex I have to reassess its original neighbor's neighbors. Which is the example cluster-array I posted.

No matter how long the cluster-array is, it's always rather short arrays (+-6 elements) that get reduced. I've been told reducing doesn't require reallocation!?

So it boils down to the question: Does LV line up all the short arrays in clusters in one long line to create the outside array? This would explain the computing time difference. If so, I'd have to come back to your idea and write some "end of array" numbers into them - which I haven't tried yet. If not, I'd still have to find my "time-hole".

Jannis

0 Kudos
Message 8 of 10
(4,073 Views)

I'llesist the urge to recreate the code you posted, just to make it more fun.

 

I think what is bogus about your benchmark is

 

The buffer shown at the input of the inplace structure is telling you the entire buffer that is holding the output of the select T/F is copied to the input of the inplace for every itration of the for loop so you are really meassuirng that operation not he stuff inside (I think). The SR on the For loops elminate the copy.

 

Folding:

folding is a term used to descibe the process when LV finds code that is invariant, does not change, so it precompiles the answer rather than comupte it at runtime. Christian's comments above will rule out folding.

 

Please show us the real code with the buffers showing so we can help with the real issue and not a contrived issue.

 

fast forward...

i think that Christian had prevously shown that fastest apraoch is to mark the tiems to delete "in-place' with a marker of some sort and latter concolidate the results so that buffer allocations, copies and mallocs are minimized.

 

But I am just specualting....Smiley Wink

 

Ben

 

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
Message 9 of 10
(4,059 Views)
Solution
Accepted by topic author Jannis

Thank you guys!

You were all right!

Steven and Ben have worked out were my bench mark test was badly set up, which Ben has perfectly explained. That test did send me on a phantom hunt expecting the time delay for large arrays at the wrong spot - the In-Place struct.

My next mistake was my local chaos with different LV-versions and 3 PCs: Altenbach and Jeff are of course right about keeping the array size constant and just marking the reduction in a separate counter. I did this at some point in a later lost version - and didn't spot the icon difference between ArraySubset and DeleteFromArray for a while...

So my time-hole had to be hidden somewhere else. Thanks Ben, unfortunately those black BufferAllocation dots are just a little bit to small for my old eyes. Didn't realize them at the end of the event and while loops!

Every 15seconds I actually shorten the large array to its real size to display it in the 3D-Graph. Now here comes the interesting bit: ArraySubset will actually reallocate memory at the end of the event and while loops, while DeleteFromArray doesn't! I'm sure that's written somewhere, just not where you easily see it...

And to make it really bad: This allocation is probably done with every loop run no matter what that case has done - slowing down every other action with it. (By the way: Just as a mem alloc happens even inside a case that doesn't execute!)

Once again thank you all. For me it's back to work after a much to long wild goose hunt.

  Jannis

ArraySubsetMemAlloc.png

Message 10 of 10
(4,017 Views)