LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Increased execution time in multiple calls to a Call Library Function node

Solved!
Go to solution

I have been given a dll with a single function, that is being called by a Call Library Function node (CLFN). Each time the CLFN is run, its execution time increases. This is with the same inputs provided and the same outputs generated. Execution starts at around 0.8 secs and linearly increases to 3 seconds, over 100 calls. It gets slower as the number of calls increase. I do not observe any significant memory changes over these calls. Exiting LabVIEW is needed to return back to a 0.8 second execution.

 

I've been working with the developer of the dll and have been told there is no such delay if the dll is called multiple times from within LabWindows/CVI environment.

 

I'll describe the calculation the dll below, but I can't understand what is going on here. I've used many dlls with the CLFN in the past and never experienced this type of behavior. How is it possible LabVIEW has this happen with the CLFN, but the LabWindows/CVI code does not?

 

The dll is a complicated trajectory generator, which has many inputs and really just outputs a double 1D array. This output array is preallocated by LabVIEW and typically is sized at 1,080,000 elements. The dll typically only populates values into a third of this array, and leaves the extra elements at zeroes. That is it returns all 1,080,000 elements each time.

Thanks for your time - Chris
0 Kudos
Message 1 of 10
(4,063 Views)

Which thread setting are you using for the CLF? I would recommend running "in any thread" in order to avoid execution slowdown. 

0 Kudos
Message 2 of 10
(3,988 Views)

The "run in any thread" option is being used and I have tried unloading the dll as explained here (http://digital.ni.com/public.nsf/allkb/77594203D78D12278625729100758BE5), without any change in behavior.

Thanks for your time - Chris
0 Kudos
Message 3 of 10
(3,986 Views)

@cbl-amo wrote:

I have been given a dll with a single function, that is being called by a Call Library Function node (CLFN). Each time the CLFN is run, its execution time increases. This is with the same inputs provided and the same outputs generated. Execution starts at around 0.8 secs and linearly increases to 3 seconds, over 100 calls. It gets slower as the number of calls increase. I do not observe any significant memory changes over these calls. Exiting LabVIEW is needed to return back to a 0.8 second execution.

 

I've been working with the developer of the dll and have been told there is no such delay if the dll is called multiple times from within LabWindows/CVI environment.

 

I'll describe the calculation the dll below, but I can't understand what is going on here. I've used many dlls with the CLFN in the past and never experienced this type of behavior. How is it possible LabVIEW has this happen with the CLFN, but the LabWindows/CVI code does not?

 

The dll is a complicated trajectory generator, which has many inputs and really just outputs a double 1D array. This output array is preallocated by LabVIEW and typically is sized at 1,080,000 elements. The dll typically only populates values into a third of this array, and leaves the extra elements at zeroes. That is it returns all 1,080,000 elements each time.


If that is indeed true, I would suspect the delay is elsewhere. can you show us the code including where you are getting those performance numbers?

 

Ben

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

Can you share your code, as well as an example of how the LabWindows code calls the same DLL? A 1-million-element array is fairly large, and if you're allocating a new array each time but the LabWindows code reuses the existing one, that might explain some of it. In particular, if for some reason you're building an increasingly large array on each call to the DLL, you could see behavior like this.

Message 5 of 10
(3,979 Views)

@nathand wrote:

Can you share your code, as well as an example of how the LabWindows code calls the same DLL? A 1-million-element array is fairly large, and if you're allocating a new array each time but the LabWindows code reuses the existing one, that might explain some of it. In particular, if for some reason you're building an increasingly large array on each call to the DLL, you could see behavior like this.


Excellent point.

 

Wrapping the dll in an Action Engine that passes in a fixed size array stored in a shift register would be a way to eliminate repeatedly allocating memory... I think.

 

Actions:

 

Init - init an array of the right size and shove it a SR.

 

Invoke - Calls the dll and passes in the array from the SR.

 

The non-growth of memory may be due to LV seeing the buffer is no longer used and returns the buffer to its inter pool of memory but the slow down may be from memory fragmentation requiring more time to find a contiguous block for the array.

 

I like that thought Nathan!

 

Ben

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

I really appreciate the input and thoughts on this situation. Unfortunately, I can't share any code, but I can share some screen captures that I hope address the suggestions. I created a simple VI for a timing study once the issue was discovered and it operates the way the dll is used in a bigger application. The graph shows the increasing execution time.Timed-01.PNG

In order to quickly see if re-using the same array has any impact, I moved the array initialization outside the for loop. As the image shows, there was no change in the execution.Timed-02.PNG

Thanks for your time - Chris
0 Kudos
Message 7 of 10
(3,963 Views)

Moving the Initialize Array hasn't changed anything because you're still requiring LabVIEW to copy the entire initialized array for each iteration of the for loop: that is, you've gone from allocating a clean array on each iteration, to copying the already-allocated clean array (because LabVIEW has to hold onto the unmodified allocated array for the next iteration).

 

What happens if you replace the array tunnels with shift registers? That should allow LabVIEW to reuse the same array on each call, although it also potentially changes the behavior of the application since on every call after the first, you're passing an array that's already been filled in once. That's where it would be helpful to know more about what is going on inside the DLL call, and how you're calling the DLL from LabWindows.

0 Kudos
Message 8 of 10
(3,958 Views)

Ha, I was thinking about using shift registers instead and had just finished testing when I saw your reply. It doesn't appear to change the behavior though.

Timed-03.PNG

Thanks for your time - Chris
0 Kudos
Message 9 of 10
(3,953 Views)
Solution
Accepted by topic author cbl-jnj

It looks like this behavior may be related to the cvirte.dll (CVI Run-time dll) functions used by our custom dll.

 

I was disappointed (and surprised) that unloading the custom dll did not reset the execution time. But by using the process explorer from the sysinternals toolbox, I noticed that the cvirte.dll came into memory along with the custom dll, but was not unloaded when the custom dll was unloaded.

 

We then created a executable in LabWindows/CVI which used the same dll, cvirte.dll, and now see the increasing times with that executable. The previous test I mentioned was done in the LabWindows/CVI development environment, which did not use cvirte.dll.

 

I've been told the custom dll can be easily changed to not use the CVI functions, so that work is being done now.

 

I'll mark this entry as the solution for now and if any extra information comes up, I'll add it at that time.

Thanks for your time - Chris
Message 10 of 10
(3,952 Views)