04-02-2013 10:52 AM
@Bublina wrote:
Hello,
Recently, I was wondering about the overhead the wait(0) brings, and it is quite big ?!?!?!?
To bash this down, here are few examples :
First standard, how many iterations do I get without any sync structures. Result = 3 750 000 iterations
Second, to see the wait structure overhead. Result = 630 000 This was quite shock, I thought it would be around 1/3 of the waitless loop.
Third, a bit shocky. Result = 34 000 So the wait structure overhead is not so huge...
I was trying to find a proposed method to control bigger architectures, but didn´t. I would like to know, if it is genrally OK to use the wait structure as control mechanism for VIs with around 100s of iterations per second, or is it better to implement these as one queue consumers, where the data might differ, just like it is in actor framework (not so comfy)?
Apart from you not trying your initial question at all; you've made no code using/testing the wait-function, it's OK to use the wait structure. However, due to windows non determinism, you cant really expect anything more correct than 5-10ms as minimum wait too keep it somewhat deterministic.
The question is ofc: What are you planning to use it for? Synchronising lots of vi's? Then Occurance or similar from the Synchronization-pallette is better. Just to keep a program running and reacting to actions? Then Event structures or queues are the correct answer. If there's some things that doesn't create events, like reading some external signal, then polling is needed.
/Y
04-02-2013 10:58 AM
@Mark_Yedinak wrote:
I try to avoid polling operations if at all possible. Your use of the Wait(0) or queue timeouts are effectively implementing polling solutions. I prefer to use event driven systems that will use either queues (with no timeouts) or user events. If I have regular processing that can occur that is not driven by the events or messages I would probably create an internal message handler that people often call a queued state machine. I would then create a separate loop that its only purpose is to wait for the external event/message. When it receives it will post that to the internal processing queue.
The actor framework is also a good design pattern.
I agree, the downside of the queued state machine, is that you need to keep all the queue refnums for all those subVIs. This becomes bothering once your app has 35 of them and you want reset/set/whatever all of them/some group.
Thats why I went with events, but you cannot use events to process data (you cannot enqueue the control command at the start of the event queue, so the VI gets easily overflooded with events) so I only use the event structure for subVI control. On the other hand, there is a hunch of HW events registerable like images/daqdata and events are the only (except occurences) supported option for external code, that I use alot. At the end of the day, it might be hard to choose what to prefer. Thats why I stick to architecture that uses events, because sometimes you just cannot avoid it.
04-02-2013 11:04 AM
@Yamaeda wrote:
The question is ofc: What are you planning to use it for? Synchronising lots of vi's? Then Occurance or similar from the Synchronization-pallette is better. Just to keep a program running and reacting to actions? Then Event structures or queues are the correct answer. If there's some things that doesn't create events, like reading some external signal, then polling is needed.
/Y
Thanks for post, the wait(0) was ment to represent the wait structure with 0 timeout, I see it is confusing.
The question starts in your bold text.
04-02-2013 11:14 AM
@Bublina wrote:
Thats why I went with events, but you cannot use events to process data (you cannot enqueue the control command at the start of the event queue, so the VI gets easily overflooded with events) so I only use the event structure for subVI control.
You can send the data in an event, and if you want a "all in one"-event (or queue) you can have it use a cluster of an Enum with command and a Variant as data, then you can easily extract command and data on the consumer/event side.
/Y
04-02-2013 11:22 AM - edited 04-02-2013 11:24 AM
@Yamaeda wrote:
@Bublina wrote:
Thats why I went with events, but you cannot use events to process data (you cannot enqueue the control command at the start of the event queue, so the VI gets easily overflooded with events) so I only use the event structure for subVI control.You can send the data in an event, and if you want a "all in one"-event (or queue) you can have it use a cluster of an Enum with command and a Variant as data, then you can easily extract command and data on the consumer/event side.
/Y
I do not think that using events for data is good, like I wrote, events will queue up and you have no option how to flush them outside of the loop. And as to the queue, I wrote, that you need to keep all the refnums and that there are several cases where you are encoureged to use the event structure.
04-02-2013 11:31 AM
Yes, there are pros and cons with events and queues, the main difference being that Events are good for One-to-many and Queues for many-to-one. 🙂
Both queues and events will queue up if you dont consume them fast enough, the Queues refnum can be had from it's name. 😉
/Y
04-02-2013 11:33 AM
Bublina wrote:I do not think that using events for data is good, like I wrote, events will queue up and you have no option how to flush them outside the loop. And as to the queue, I wrote, that you need to keep all the refnums and that there are several cases where you cannot avoid the event structure.
Well you have succinctly summarized the disadvantages. Events will enqueue and you cannot flush them. You CAN unregister for them though, if you use dynamic events. Dynamic events are a viable option in most cases where you want to respond to stimulii "sometimes."
I would like you to clairify the bold text statement. Data is data, events happen. What did you mean by that?
04-02-2013 11:55 AM - edited 04-02-2013 12:07 PM
@JÞB wrote:
Bublina wrote:I do not think that using events for data is good, like I wrote, events will queue up and you have no option how to flush them outside the loop. And as to the queue, I wrote, that you need to keep all the refnums and that there are several cases where you cannot avoid the event structure.
Well you have succinctly summarized the disadvantages. Events will enqueue and you cannot flush them. You CAN unregister for them though, if you use dynamic events. Dynamic events are a viable option in most cases where you want to respond to stimulii "sometimes."
I would like you to clairify the bold text statement. Data is data, events happen. What did you mean by that?
Jeff, you can unregister and register, but what is it good for, if you do not know how many events(with data) pending + you cannot flush it outside of that subVI (you would have to redistribute the event reg refnum - omg).
I ment and mean events in LabView, those happen and carry data...
Since all of you have valid arguments but the discussion is going nowhere, I will stick to the fact that most of you do not use the wait structure in places where processing is essential. I will implement sort of hybrid model and avoid using event structure a bit more than I used to...
I sort of a miss the WaitForMultipleObjects function analogue.
04-02-2013 05:53 PM
Maybe i'm just tired, but i dont understand what your goal is? You talk about waits and overhead and events and queues.
They are quite different tools with different functions. In all normal instances of a event or queue you dont want any waits as it should go as fast as possible. They are per design asynchronos. If it's about working on data sets an Action Engine if often a good tool.
Synching through a wait is just hoping for the best as it's not the best tool for the job. If you want to synch things you'll use Occurance or notifier.
Or what's the goal?
/Y
04-03-2013 06:25 AM - edited 04-03-2013 06:26 AM
While i find the discussion, which is drifting from the original question, very interesting, i will try to answer/comment the original question.
First of (and most important):
There is no "wait structure" in LabVIEW. Never heared of that term either except than this thread.
Your screenshots in the OP shows the EVENT structure using the TIMEOUT case.
That being said, we already have the explaination why the untimed while loop iterates more than any other loop in a given time (in your case, 100ms, which is way too low for a proper benchmark, but good for showing tendencies):
The untimed loop hogs one CPU core with 100% and will only release it if
- the thread has finished
- a higher priority thread "pre-empts" it.
The wait functionality (regardless of the mechanism which introduces it) will enable other threads to get grasp on the CPU core for a short time which will naturally lower the amount of iterations.
My system returns comparable results to your for the shown scenarios in the OP. Using a wait(0) returns about 1.8M iterations, which is about 50% compared to "no wait".
Using other mechanisms for waiting (Event structure, Queue/Notifier, ... ) will add additional overhead.
Event structure:
The event structure will react on events enqueued in the event queue. This is first of all a LV internal event queue. The LV event mechanism is tightly associated to the Windows event queue and partly "shares" events, which means that they are enqueued in LV as well.
The timeout event is a good example: LV tells the OS that the thread has to wake up after X ms, and the thread is put to sleep (or used for other "clumps"). So the OS will enqueue the event which is "forwarded" to the event structure queue. This introduces additional overhead compared to the wait(0). The result being obvious in your "benchmark".
Notifier/Queues/... work very similar regarding the timeout functionality. I assume that checking for elements is done before handling the timeout event which adds new overhead compared to the timeout event of the event structure. Hence, benchmark results still going "down".
I havent checked for further event based "wait" events (better talk about "timeout"!), but i would expect them not to exceed the event structure results.
The main question remains (which is topic of the current discussion as i understand it):
Why would anyone hog the CPU core on purpose for a long time using timeout events?
Norbert