I am pretty surprised to hear so many people clamoring to keep the top level VI laden with code. In nearly all of the other languages (admittedly those crude text based ones) the convention is to keep main() or its equivalent relatively codeless, except to start the necessary objects or loops. Let me be the first to say the analogy between the top level vi and main is not wholly accurate, but they are certainly similar. But from some simple benchmarks, it is apparent that moving indicator updates out of their "native" diagram is a serious performance hit. This, IMHO, is absurd and should not be.

Now, performance aside, why is it so critical to have all of the panel update contained in one potentially mammoth vi? It is no big deal if there are only a few indicators. But when you start really piling them on, managing them becomes a pretty big deal. Now it might not be such a hot idea to scatter front panel writes throughout the application, but I don't think it is a great idea to confine them only to their diagram either, especially when that diagram is the top level. The obvious, to me, compromise it to keep some sort of queue driven UI update, but use references to move that into a sub-vi. Now, since it is by reference, the updates would not have to all be in this singe sub-vi either. Instead, they could be scattered all over the UI update hierarchy. If you are married to the idea of keeping every update in one diagram our goals are intrinsically incompatible. I personally find such an approach impractical, and that is what started this idea in the first place. But I can see how the other end of the spectrum is fraught with confusion. If an update can happen anywhere, it will soon happen everywhere.

So it would seem like the idea of globally available references to the top level indicators is probably NOT good programming practice, but I am still latched on to the idea of moving the updates into their own sub-hierarchy and out of the top level. This will incur the by reference performance hit, but for now that is not a big deal for me as I only need about 0.5 updates/sec. And when the time comes that I need better performance I expect NI will have sped up the reference operations ;)

Okay... some simple benchmarks. numbers are updates/sec for an xy graph of 2000 points (random numbers)

1139 - no update, calculation only
942 - direct wire
132 - by value (directly linked property node)
128 - by reference, same panel
128 - by reference, sub-vi
125 - by value, signaling (directly linked property node)

George


Hmm, why is this a mess? It makes perfect sense to me. The only access
to the front panel via remote VI's is through a well defined interface.
You setup your messages and your data types and the update stays in the
main menu as it should. If a VI needs to update the front panel then it
posts a message on the queue with a specific update command. Queues have
been around for a while and it has been proven by many on this list to
be a very efficient method of communication between parallel processes.
I would re-think your comment on a queued architecture.

Using control references breaks out of the object oriented methodology.
Manipulating VI panels directly via other modules means I need to know
everything about the Main VI for me to update the panel. In many cases,
updating the front panel involves more than just dumping data to a
control. It may involve processing the data and possibly changing
several parameters of the Main VI. It is best to let the Main VI do what
it does and knows how to do. Using the control reference approach means
I now have my Main VI scattered in 100 different places. Where do I go
to fix a bug? Also, can two programmers work on the same code at the
same time?

To comment on the use or overuse of references, I would have to say that
on the totem-pole of efficiency, they rank on the bottom of the list as
far as update speed. The order of efficiency would be (correct me if I'm
wrong):

1-Wire directly to terminal (ah yes, the good ol' days)
2-Wire to a local variable
3-Wire to a "value" property node on the same diagram as the control.
4-Wire to a "value" property node via a cotrol reference

The reasoning behind what approach to take depends on the situation of
course. One thing to consider is, will the application ever be
augmented? If so, you want to implement a strategy that will accommodate
future growth without sacrificing speed or code clarity.

I think a balanced approach is preffered over a strict rule of
methodology. Personaly I  use "all of the above" in some form or
another. My main communication "engine" is a queue and at the local
level I use control references and locals wherever modularity and code
reuse permits it. Nothing however beats method#1. I use this whenever
large amounts of data are being pumped to a graph. Graph updates are
always bottlenecks. How do I use method#1 and still pass data via
sub-VI's to the front panel? Easy, I use a shift-register global
(functional or LV2 style). I can write data into it from a sub-vi and
read it from a main VI. It is very efficient for large arrays or
structures.

I'm not saying that you should never use cotrol references. However, I
would be hesitant to base my whole application design and communication
around something that is inherintly slow and doesn't allow the
flexibility of queues or message passing.

Thank You
Michael Aivaliotis




Reply via email to