I go on vacation for a week and I come back to this?
Dogs and cats living together...
Well see what happens!
In this thread I swore off Globals once and for all.
My application is satisfactory without the globals and I am "off the [global] bandwagon" for another 5 years.
Your timing is impeccable!
Flat out bench-marks on just the global may trick you into thinking they are faster but they simply do not allow working in-place.
Did you see the idea I posted on the exchange that prompted this silly thread that somehow devolved into a thread about sequence structures? The idea was just a simple refactoring tool to convert globals into FGs because I inherited something I would rather not discuss. The idea was declined so quick (the next day - a world record?) that I thought that globals really were faster. I did see earlier in this thread that Matthew did some benchmarking on a DBL global vs a FGV and the global won. I don't know if debugging was disabled or if the execution priority was changed.
But there is a bright side. Although my idea was declined the status was just as quickly changed to In Development by Felix
Thanks Steve for such an informative and lively thread.
You will have to visit the sister thread in the Ideas Exchange that I just posted:
Coming in late here but my take on this is simple:
Globals are BAD and FGVs (or AE - Action Engines) are GOOD
There are many reasons and most have been named already.
One thing, if you use singular global variables (this includes also FGVs simply for the purpose of storing a value only) for data items you probably need to rethink the design. Those data usually are more complex than a single floating point value, and at the same time have nothing todo with configuration values, etc. So creating a FGV/AE (or for modern people LVOOP) for the set of data related with each other is usually a better idea.
Raw access for a global is faster than for a FGV call but the difference could be minimized with subroutine priority. However those access times are only really relevant if you access the value many times in a tight loop and then reading/writing to a global (even in the form of a FGV) is a completely wrong idea anyhow.
On the other hand an FGV or LVOOP can incorporate smart operations way beyond just reading or writing that value and then you quickly are much faster than reading that global doing something on it and writing it back into the global.
So I stand at my original credo: Global use is BAD!!
Well said Rolf.
Especially the part about being modern with the use of LVOOP.
If the performance and architectural issues of the application are understood there are situations where global variables are perfectly benign. I agree with Darren and NIs offical position that they are probably a better choice than other methods of storing global data for certain use cases.
In spite of the intentional attention grabbing title of this thread I do not recommend always using them for everything.
Agreed. And that is what I get when reading Darren's blog:
"global variables are not evil. There are perfectly valid use cases in which a global variable is the best tool for the job, and doing something more complicated just to say, "I didn't use globals!" doesn't make sense. Now sure, globals can be abused, and there are certainly scenarios where they are contraindicated. But if you're aware of those situations, and you avoid them, you should feel free to use globals where needed."
EDIT: And Darren does mention and make reference to the WORM, which we have not discussed in this thread 😉 Whether tbob's WORM or using the Global as WNRM (although you do have to write to the GLobal once to set the values... ), those are definite cases where Globals make sense. Thanks Darren for a nice blog.
Since people know how I feel about Locals, I must say that I am not "anti-Global". I'm anti-abuse. Heck, in some cases I would use Globals over FGV, without question. An example would be as a holding place for the GIPB addresses of instruments. It is highly static data that is read in the software. I would NOT use a Global for data transactions (dynamic reading & writing). As a matter of fact, unless I use an Action Engine, I would not likely use a FGV. There are much better ways of handling incoming & outgoing data. To me, the Global was not created with that functionality in mind.
I would replace Broken Arrow's suggestion for Guru to use LVOOP. 😉
The appropriate choice depends on the context... Is it just to set and get a single boolean? What's the purpose of the boolean? Etc..
You could use any of the suggested methods to replace a wire (although a queue would be far-fetched.. but not impossible) << hey!! you've all seen strange code out there... I did not say I would do it!! 😉
And Darren does mention and make reference to the WORM, which we have not discussed in this thread 😉 Whether tbob's WORM or using the Global as WNRM (although you do have to write to the GLobal once to set the values... ), those are definite cases where Globals make sense. Thanks Darren for a nice blog.
It is surprising that WORM did not come up until now. But I think Darren really did mean that he never writes to the global. He didn't specifically say so but I think what he does is to open the global vi front panel, edit the values, make them default, then save the global. Neat trick. But the programs I write get deployed to systems without the development environmnet so that wouldn't work for me. I save that type of data in either an INI or XML file.
I would replace Broken Arrow's suggestion for Guru to use LVOOP. 😉
Then it would loose it's circular nature. But LVOOP definately belongs in there. Hope he doesn't mind
In general, communicating between loops within the same VI is done with Queues or Notifiers. It's most common for controling states between the two loops (as in the Producer\Consumer or Master\Slave structures) but you can wire a cluster for local data. You could theoretically name the queue to send data over multiple VIs (assuming they are both running at the same time), but I never see it done so I doubt it's very efficient compared to globals.
If you want to do send data within one VI, you could use local variables so LabVIEW doesn't have to put it in global memory.
Basically, the improvement from globals to functional globals is that you can Initialize, Clear, etc. your globals more simply. Doing these extra functions are vital for ensuring you're not sending old data! Yikes! Other people showed more specific items (I might just create a subVI with the basic get/set vis within it to handle more complex things, but that's just a preference thing). Then functional globals may be better to keep your programs consistent and modular.
In general, I try to avoid Globals because most of our programs have a bunch of VIs which are dynamically called to run in a specific sequence. Variant clusters work well for this if they are strung through all VIs and initialized in the first. But maybe it's just giving me an unneeded sense of control and security.
Basically, the improvement from globals to functional globals is that you can Initialize, Clear, etc. your globals more simply.
To help with the concepts, I actually make a distinction between a Functional Global Variable and an Action Engine. What you describe here is an Action Engine. A FGV is simply an AE with just Get and Set actions.
You might also want to visit my NI Week session page (TS9454 - Are Global Variables Truely Evil?) to get into the discussion some more.