LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

what would cause one read of a global be slower than another?

Thank you for the correction Wile-E.!

I appreciate the correction.

For those that have not seen it yet, please read my BLOG entry "he that loveth him chasteneth him "

that can be found in the LabVIEW Champions BLOG page found here.

http://forums.lavag.org/blog/champions/index.php?

Ben

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
0 Kudos
Message 11 of 47
(4,608 Views)

OK testing indicates that I stay with the LV2 version.

Here is a screen shot of my benchmarking.

Stay tuned!

Ben

Message Edited by Ben on 03-23-200611:33 AM

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
Message 12 of 47
(4,606 Views)

Hi Ben, Hi all,

This is what I call a great and very interesting thread... Thanks Ben for sharing your experience and observations.

What surprises me is that you chose to use a global (wich in my opinion is not the appropriate tool for this) just because of speed conciderations, am I wrong ?
And now, you aparently decided to come back to FGV - but still because of speed conciderations...
Is you application such time critical that you need to worry about a fistfull of u-seconds ?

I am not sure about how works global variables but I assume that it is duplicated many times in memory and so I am not surprised that problems occur when you read it from many different parts of your app.

Only concidering the description of your "stop process" I would have chosen a notifier or queue, I think an empty queue would be nice in terms of "coding style", no ?
An queue queue read in all your loop, with a "preview queue" to read and get the "timeout" output to know if the loop has to stop ; like this you can put anything in your queue that doesn't matter since it will never be read, just the information that "something" is in will be the stop source.

In addition, with a Release Q  with "destroy queue" to false in each loop, you are sure that the queue will be destroyed only after all your VIs have read it... isn't wonderful ?


BTW, there are my results... I am really surprised that global are so fast to read and Q so slow... Smiley Indifferent


Message Edité par TiTou le 03-23-2006 07:32 PM


We have two ears and one mouth so that we can listen twice as much as we speak.

Epictetus

Antoine Chalons

Message 13 of 47
(4,583 Views)

HI Titou,

See my replies inserted into your text.

--------------------------------------------------------------------------------------------------------

This is what I call a great and very interesting thread... Thanks Ben for sharing your experience and observations.

[Ben] Thank you and you are welcome!

What surprises me is that you chose to use a global (wich in my opinion is not the appropriate tool for this) just because of speed conciderations, am I wrong ?

[Ben] Yes sir! I am devloping a "crazy" application. We are up 30,000 "channels" with sample rates that vary from 1-1000 Hz.


And now, you aparently decided to come back to FGV - but still because of speed conciderations...
Is you application such time critical that you need to worry about a fistfull of u-seconds ?

[Ben] Yes Sir! When completed, this application will have to settle arguements about which part of the system failed to what they were supposed to do and when. Portions of the 30,000 channels will be coming from descrete systems that need to interact with each other as specified. In the final phases all of the contituents of the system I will be monitoring will be syncronized via IRIG-B and crystal clocks.

I am not sure about how works global variables but I assume that it is duplicated many times in memory and so I am not surprised that problems occur when you read it from many different parts of your app.

[Ben] Good observation, stay tuned.

Only concidering the description of your "stop process" I would have chosen a notifier or queue, I think an empty queue would be nice in terms of "coding style", no ?
An queue queue read in all your loop, with a "preview queue" to read and get the "timeout" output to know if the loop has to stop ; like this you can put anything in your queue that doesn't matter since it will never be read, just the information that "something" is in will be the stop source.In addition, with a Release Q  with "destroy queue" to false in each loop, you are sure that the queue will be destroyed only after all your VIs have read it... isn't wonderful ?

[Ben] Yes that is a valid approach but again see my comments above on performance. The dynamic loading of components into this application makes that approach a little more cumbersome. The top level VI will at some time become "fixed" while I will have to develop new components at a future date. I can dictate that the "Global stop" wil always be there when I have to deploy future components.


BTW, there are my results... I am really surprised that global are so fast to read and Q so slow...

[Ben] Yes, a factor of 100 can not be ignored. That is why I broke my rule about "not using globals" just to pick up that performance delta. But like I said, stay tuned!

 

Ben



Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
Message 14 of 47
(4,575 Views)
Woaw man... that sounds quite huge !

I had no doubt you had good reasons to choose a global variable for you stop process.

And I totally agree that software developers MUST respect rules and guidelines, but also need to be allowed to break them under special conditions 😉

Let's stay tuned 🙂


We have two ears and one mouth so that we can listen twice as much as we speak.

Epictetus

Antoine Chalons

Message 15 of 47
(4,547 Views)

Final Update (?)

After testing and personally witnessing the results this is what we found.

1) Globals are still evil. Eliminating these got rid of "Finished Late" issue due to dragging windows around. The theory is that the global reads are using the UI thread.

2) One of the 600+ VI's was passing a bad "Period" value into one of the timed loop sub-VI's. This is what caused the "Finished Late" issue when that module was used.

3) The remaining failing module will be restructured to stream line its processing.

 

General observations:

1)Contrary to the benchmark work that compares the LV2 with the traditional global, there was very little difference between using the two methods. That implies (to me) that vey little of actual processing work involved determining if it is time to shut down. Concidering the problem the globals caused by running in the UI thread (not sure on this detail) the better performance of the globals was of no use.

2)It looks like the "Finished Late", "Expected End" and "Actual End" reflect the results of the previous iteration of the timed loop (This distrurbed the data flow paradigm part of me). Smiley Wink


Once again, I thank you for sharing your ideas.

Ben

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
Message 16 of 47
(4,514 Views)
Hello all,
 
I realize I'm chiming in here late - I only first saw this thread today.  In any event, the center of speculation seems to be on whether global variables run in the UI thread or not.  The short, direct answer to that question seems to be yes, however there is more to the story.  It is summarized as follows:
 
"When you write to a local or global variable, LabVIEW does not switch to the user interface thread immediately. LabVIEW instead writes the value to the transfer buffer. The user interface updates at the next scheduled update time. It is possible to update a variable multiple times before a single thread switch or user interface update occurs. This is possible because variables operate solely in the execution thread.

Functional global variables can be more efficient than ordinary global variables because they do not use transfer buffers. Functional global variables exist only within the execution thread and do not use transfer buffers, unless you display their values on an open front panel."

For a description of what a "transfer buffer" is and how it is used as LabVIEW switches between the execution and user interface thread, the following was taken from the same source as the quote above:

"Completing user interface actions uses more memory because LabVIEW switches from the execution thread to the user interface thread. For example, when you set the Value property, LabVIEW simulates a user changing the value of the control, stopping the execution thread and switching to the user interface thread to change the value. Then LabVIEW updates the user interface data and redraws the control if the front panel is open. LabVIEW then sends the data back to the execution thread in a protected area of memory called the transfer buffer. LabVIEW then switches back to the execution thread. The next time the execution thread reads from the control, LabVIEW finds the data in the transfer buffer and receives the new value."

For the complete LabVIEW 8 help page from which the quoted information above was taken (and below), here's the title and link:

Title: VI Execution Speed

Link: http://zone.ni.com/reference/en-XX/help/371361A-01/lvconcepts/vi_execution_speed/

Further, I believe the statement "Functional global variables exist only within the execution thread and do not use transfer buffers, unless you display their values on an open front panel."  draws the contrast between "things that live in the user interface thread" (in this case local and global variables) and "things that live in the execution thread" (in this case noting functional globals as a relevant contrasting example).  Thus, in general we are drawing a distinction between things which live in the UI thread but don't necessarily cause a swap to the UI thread immediately (local and global variables), other things which do cause a thread swap immediately (property nodes), and yet other things which don't cause a thread swap to the UI thread at all (functional globals - assuming a front panel isn't open displaying their values).

Best regards and have a great weekend!

JLS

Message Edited by JLS on 03-24-2006 04:19 PM

Best,
JLS
Sixclear
Message 17 of 47
(4,490 Views)

Thank for that additional inof.

the phrase "The next time the execution thread reads from the control, LabVIEW finds the data in the transfer buffer and receives the new value."

still leave me wondering "in which thread is the 'finding the data in the transfer buffer and recieves the new value' performed.

My experiments mentioned previously seem to confirm that this happen in the UI.

So True or False ?

The UI thread is used to read a global.

 Thank you,

Ben

 

 

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
Message 18 of 47
(4,462 Views)
I have the same doubt but with respect to property nodes:
Does LV go to the UI thread only when writing to the value property OR does it also switch to the UI thread when reading from the value property?
 
 
My front panel is highly user interactive. Which means lots and lots of controls/indicators that are read/written many times across the code. I have been sticking to Property Nodes (!) but cannot continue doing so for very long because of speed considerations. I am not sure how LV2 globals can help me because to my knowledge they are best used when you wish to hold data without showing it on the front panel.
Maybe I am missing some very simple concept here and would be glad to be informed.
 
Rgds,
Gurdas
Gurdas Sandhu, Ph.D.
ORISE Research Fellow at US EPA
Message 19 of 47
(4,459 Views)

HI Gurdas,

I think I can help with part of your Q's. See my replies inserted in your text.

"

I have the same doubt but with respect to property nodes:
Does LV go to the UI thread only when writing to the value property OR does it also switch to the UI thread when reading from the value property?
 
[Ben] All property nodes execute in the UI thread. If your VI is NOT configured to run in the UI thread and it comes time to execute a property node, the thread is changed to the UI thread the property node is executed and then the VI CAN switch back to the orignal thread. The processing of swithing between threads is costly.
 
 
My front panel is highly user interactive. Which means lots and lots of controls/indicators that are read/written many times across the code. I have been sticking to Property Nodes (!) but cannot continue doing so for very long because of speed considerations. I am not sure how LV2 globals can help me because to my knowledge they are best used when you wish to hold data without showing it on the front panel.
Maybe I am missing some very simple concept here and would be glad to be informed.
 
[Ben] For applications that demand a lot of CPU, I try to prevent the additonal work of thread swapping to and from the UI thread. To do this, I keep the "real data" in LV2's functional globals, action engines. If the "real data" changes, I'll use it to update the GUI. If it changes often, I limit the number of UI updates by just showing the "last value" rather than trying to kill a lot of CPU just to unpdate an indicator that I will re-update 30ms later.
 
For control on the UI, the Event structure lets me copy the new value frm the UI in the LV2 only when it changes. Once in the LV2 I can use the value as many times as I want and never have to enter the UI thread unti lthe user punches another button.
 
"
 
I hope this helps,
 
Ben

Message Edited by Ben on 03-25-2006 10:46 AM

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
Message 20 of 47
(4,450 Views)