From: Charlie S. on
Hello Aaron,
 
This sounds like an interesting issue. The difference in execution times for the subvi with the constant or the tick timer is so close, it's hard to say that anything significantly different is happening there. The difference with the DLL, however, is very significant!
 
I have tried playing around with this a little myself. I wrote a very simple DLL (using CVI) that just adds two numbers together. Using the tick count or integer constants as inputs to the call library function node, I could not reproduce the difference you describe (using LabVIEW 8.0.1). Thus, I have some questions for you:
 
1. What version of LabVIEW are you using?
2. What operating system?
3. Are you running the CLFN in the UI Thread or is it set to Reentrant?
4. Can you post your code and your DLL so that others can give it a try? (or at least something that reproduces the problem?)
 
I am interested to help you figure this one out. Let me know what you find out!
From: Charlie S. on
Hi Aaron,
 
Thanks for posting the code -- that made things a lot clearer for me. I believe I know what's going on here, and the good news is that it's easy to correct! (You shouldn't apologize for this though, as even an experienced LabVIEW programmer could run into a similar situation.) Let me explain...
 
When you set your Call Library Function Node to run in the UI Thread you're telling LabVIEW that your DLL is not Thread-safe -- this means that under no circumstances should the DLL be called from more than one place at a time. Since LabVIEW itself is inherently multithreaded the way to work with a "thread-unsafe" DLL is to run it in a dedicated thread -- in this case, the UI thread. This safety comes at a price, however, as your program will have to constantly thread-swap to call the DLL and then execute block diagram code. This thread-swapping can come with a performance hit, which is what you're seeing in your application.
 
The reason your "MSTick fine behavior.vi" works is that it isn't swapping threads with each iteration of the for loop -- same with the "MSTick bad behavior.vi" without the Tick Count function. When you introduce the Tick Count Function in the for loop, LabVIEW now has to swap threads every single iteration -- this is where your performance issues originate. In fact, you could reproduce the same behavior with any function (not just TIck Count) or any DLL. You could even make your "MSTick fine behavior.vi" misbehave by placing a control property node in the for loop. (Property nodes are also executed in the UI thread).
 
So what's the solution? If your DLL is thread-safe, configure the call library function node to be "reentrant." You should see a pretty drastic reduction in the amount of time it takes your code to execute. In general, you can tell if your DLL is thread-safe when:

- The code is thread safe when it does not store any global data, such as global variables, files on disk, and so on.

- The code is thread safe when it does not access any hardware. In other words, the code does not contain register-level programming.

- The code is thread safe when it does not make any calls to any functions, shared libraries, or drivers that are not thread safe.

- The code is thread safe when it uses semaphores or mutexes to protect access to global resources.

- The code is thread safe when it is called by only one non-reentrant VI.

There are also a few documents on the website that you may want to take a look at, if you want some more details on this:
<a href="http://zone.ni.com/reference/en-XX/help/371361A-01/lvexcodeconcepts/configuring_the_clf_node/" target="_blank">Configuring the Call Library Function Node</a> <a href="http://zone.ni.com/devzone%5Cconceptd.nsf/webmain/B26A875ACA51C567862567CA0055FF24" target="_blank">An Overview of Accessing DLLs or Shared Libraries from LabVIEW</a> <a href="http://zone.ni.com/reference/en-XX/help/371361A-01/lvconcepts/vi_execution_speed/" target="_blank">VI Execution Speed</a>
I hope this helps clear-up some confusion -- best of luck with your application!