LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Getting data from SendMessage function

Update:  I didn't need the new thread so I was able to simplify it a bit.  I just use the LVUserEvent for notifiying the VI from the wrapper DLL callback function (this happens when an interrupt occurs.  Then I just block on a semaphore in the callback.  When the Vi is done, it calls a new function in the wrapper DLL that just posts the semaphore to unblock the callback.  Seems to work fine, but LabVIEW seems a little slow.  I think there's too much screen repainting going on.  How can I control that?
Message Edited by garya505 on 03-20-2010 04:12 PM
0 Kudos
Message 11 of 22
(1,914 Views)

Try to not use the callback for once and see if that makes a difference. The external component that you are calling may play tricks with the applications message loop while it is inside the callback. LabVIEW's UI thread does serve that application message loop and also does all the repainting. So if your component is somehow messing with the message loop it could severaly hamper the performance of LabVIEW.

 

This does not have to be done intentially by the component. For instance if it is based on an out of process ActiveX or COM component internally it may have to do something called marshalling. This happens usually automatically for properly created components but especially for the callback case this is a very tricky business and ActiveX does hook somehow into the applications message loop to implement out of process marshalling.

 

So disable the callback mechanisme and see if that has any significant influence on the sloppyness of your application. If it has I would guess that is a though cookie and otherwise look at your application and how you could improve its performance. There are several good guidelines and stylebooks out there that also give tips how to improve performance.

Message Edited by rolfk on 03-21-2010 10:16 AM
Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
Message 12 of 22
(1,901 Views)

Thanks for the tips, I'll try it. 

 

I'm not using ActiveX or COM.  When in interrupt occurs on the card, the callback function in my wrapper DLL gets called by the firmware on the card.   The firmware blocks on the callback function to prevent simultaneous memory access. The callback function posts a LabVIEW User Event using PostLVUserEvent, which is handled in a LabVIEW VI.  The callback blocks on a semaphore.  When the callback is finished doing whatever it needs to do, it calls a wrapper function whick posts the sempahore to release the callback function.  When the callback function exits, the firmware unblocks.

 

The VI may need to use a CLFN to do it's work (for example, reading data from the card).  However, I can probably push that work into the callback itself, eliminating the need for the CLFN.  However, the VI must still use a CLFN to call the wrapper function to post the semaphore.

 

Can I use a LabVIEW semaphore as a regular C semaphore, or a C semaphore as a LabVIEW semaphore?  This would eliminate the other CLFN.

0 Kudos
Message 13 of 22
(1,884 Views)

You didn't answer the question if the sloppyness is only observed while the callback is active or also otherwise. If it is even when no callback is active, you most probably just have created a sloppy LabVIEW progam in general, by violating some of the styleguide and LabVIEW performance recomendations.

 

If it is only during the callback then you will have to investigate into that. Not having seen your driver DLL source code I can not really comment on what else could cause such a problem. I assume at least that when you use the term firmware you do mean your driver DLL. Because a firmware on the card itself could never possibly post an event to LabVIEW.

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 14 of 22
(1,882 Views)
Sorry, I just got your previous post this morning and I'm trying that now. 
0 Kudos
Message 15 of 22
(1,878 Views)
I removed all the CLFN from the event loop, so it just counts the events and calculates the event rate.  The card is getting 30 frames/second from the transmitter.  I get about 15/sec calculated in the VI, about the same as with the CLFN calls in place, so it appears that it is not the CLFN calls that are the problem.  When I stop data flow in the card,  the event loop continues on for a while, indicating that the events are getting queued as expected.
0 Kudos
Message 16 of 22
(1,861 Views)

I cleaned my development VI code (and removed all CLFN calls) but could only get about 20 events/second.  Then I created another small VI with too loops - one to generate events (producer) and one with an event structure which just counts them (consumer).  Playing with the loop delays and a an interval divider I found I could get 500 events/second without too much trouble.  This is with no CLFNs, no PostLVUserEvent, and no DLLs. 

 

The big difference is that my little test VI presumably is running two threads in the same VI, while my development VI has an event loop to handle user input and a an event loop to handle the incoming events.  The events are produced in my wrapper DLL using PostLVUserEvent.  The thread that calls the function that calls PostLVUserEvent is actually in another "base" DLL.

 

Like this:

 

1. Base DLL runs a thread that waits for a local interrupt from the hardware

2. When the Base DLL senses an interrupt, it calls a "callback" function in the wrapper DLL

3. The "callback: function in the wrapper DLL calls PostLVUserEvent

4. The "WaitForEvents" VI uses an event structure in a loop to count the events.

 

local interrupt -> base DLL thread -> wrapper DLL callback function ->  PostLVUserEvent -> LabVIEW event structure in while loop

 

So, there are some possible causes for the slow performance:

1. Overhead in PostLVUserEvent call?

2. Thread switching?

 

 

 

0 Kudos
Message 17 of 22
(1,837 Views)

Did you use User events to post the producer events to the counter loop? Because if you just use a queue for instance it will certainly be faster. I'm not sure if native user events are handled synchronized, meaning inside the UI thread, but I'm pretty sure that PostLVUserEvent may actually be synchronized through the UI thread to prevent possible multithreading problems.

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 18 of 22
(1,828 Views)

I made a test VI to see if there was a substantial problem in posting user events either natively or through the PostLVUserEvent function.

 

The result is that both methods work very similar resulting on my machine in about 110 events per ms.

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 19 of 22
(1,822 Views)

I used a User Event in both cases, since that is what I need to use to post the event from my wrapper DLL.  I'm not sure how I would use a queue (I've only been using LabVIEW for 2 months now).

 

I modified my simple test VI to use the same consumer loop, but turn on the hardware to generate the events. I'm getting 30 events/sec which is the correct rate.  I think I'll keep adding the things I need and watch for the rate to drop, then I'll know when I've done something to cause the delay.  To get full synchronization, I also need to be able to post a semaphore back to the wrapper DLL, so testing that will be my next step. 

 

One thing is clear though - calling a VI after getting the event causes a significant delay and I can only handle ~10 events/sec. 

 

I am building a SDK for LabVIEW developers to use our hardware, so I only need to know that a well-written VI will be able to handle the event rate, and that my chosen method for handling the events will work at that rate.  Once I have proven that the wrapper DLL and any supplied VIs work,  then I just I need to be able to give our customers some guidelines on what they can and can't do in their own application VI.   

 

0 Kudos
Message 20 of 22
(1,817 Views)