06-11-2018 01:44 PM
@jfalesi wrote:
If I understand correctly, you're proposing an event structure in a parallel thread?
I am proposing an Event Structure in a loop within your GUI VI. If you had controls, this would handle all of the control events as well. But you can just use User Events to send messages to this Event Structure and update your GUI however you need to. You can use the simple trick like is often done with QMH where the data type of the event is a cluster containing an enum or string to say what the data is and then a variant to hold the actual data. Then you just have a case structure based on what the data is, convert the data accordingly, and write directly to the terminal(s) of the indicator(s). I have found this to be a lot more performant than passing references and writing the value via a property node.
06-11-2018 01:58 PM
@crossrulzI am proposing an Event Structure in a loop within your GUI VI. If you had controls, this would handle all of the control events as well. But you can just use User Events to send messages to this Event Structure and update your GUI however you need to. You can use the simple trick like is often done with QMH where the data type of the event is a cluster containing an enum or string to say what the data is and then a variant to hold the actual data. Then you just have a case structure based on what the data is, convert the data accordingly, and write directly to the terminal(s) of the indicator(s). I have found this to be a lot more performant than passing references and writing the value via a property node.
I want to make sure I understand you: Right now, other than the GUI AE that I'm working on, I don't have a GUI VI per se. The "GUI" is the front panel for the main VI. Are you recommending a GUI event structure in a separate GUI VI, or in the GUI AE, or can the event structure be in a parallel thread in the main VI? Attached is the main VI in its current state. The indicator "GUI" is circled below.
06-11-2018 02:38 PM
1. Very few people will have LabVIEW 2018 installed. My company's server has not been updated yet to allow a 2018 license yet. So please use File->Save For Previous Version when posting to the forums.
2. You really need to get away from using the Value Property Node. It is HORRIBLY slow. And I am talking in the 2000 - 3000 times slower than reading/writing from/to a local variable. The property node forces a thread swap to the UI thread and a panel redraw each time you call it. So please use the terminal whenever possible, the local variable when forced to. Yes, this applies to any references you are passing around as well.
3. You might want to look into a simple State Machine instead of relying on the Sequence Structure so much.
4. Based on your current architecture, yes you will need a parallel loop to handle the events in your top level VI. Also based on your architecture, you could instead use a simple Queued Message Handler to update your indicators. I will sometimes recommend this since most people don't seen to know User Events, but Queues are quite familiar.
06-11-2018 03:01 PM
@crossrulz wrote:
1. Very few people will have LabVIEW 2018 installed. My company's server has not been updated yet to allow a 2018 license yet. So please use File->Save For Previous Version when posting to the forums.
2. You really need to get away from using the Value Property Node. It is HORRIBLY slow. And I am talking in the 2000 - 3000 times slower than reading/writing from/to a local variable. The property node forces a thread swap to the UI thread and a panel redraw each time you call it. So please use the terminal whenever possible, the local variable when forced to. Yes, this applies to any references you are passing around as well.
Thanks for the tips.
1) Saved for LV 15.
2) I started on this project by inheriting code that used local variables all over the place. There was a bug that caused previous values to be used after some variables were updated, I researched the problem (probably on NI forums or StackOverflow), and I traced it to the use of local variables. Value properties were the proposed solution, so now I use them instead... Live, learn, un-learn, re-learn, repeat 😄
06-11-2018 03:18 PM
@jfalesi wrote:
@crossrulz wrote:
1. Very few people will have LabVIEW 2018 installed. My company's server has not been updated yet to allow a 2018 license yet. So please use File->Save For Previous Version when posting to the forums.
2. You really need to get away from using the Value Property Node. It is HORRIBLY slow. And I am talking in the 2000 - 3000 times slower than reading/writing from/to a local variable. The property node forces a thread swap to the UI thread and a panel redraw each time you call it. So please use the terminal whenever possible, the local variable when forced to. Yes, this applies to any references you are passing around as well.
Thanks for the tips.
1) Saved for LV 15.
2) I started on this project by inheriting code that used local variables all over the place. There was a bug that caused previous values to be used after some variables were updated, I researched the problem (probably on NI forums or StackOverflow), and I traced it to the use of local variables. Value properties were the proposed solution, so now I use them instead... Live, learn, un-learn, re-learn, repeat 😄
What you have to learn and apply here is a State Machine, and using Shift Registers (plus if needed, one or more parallel loops). The code which you inherited was done by a "programmer" who probably had little knowledge in LV, but had some text based programming language background. The most common sign for this when someone abuses local variables, and Flat Sequence Structures. Here is a good read which can give you more hints: http://www.ni.com/newsletter/51735/en/
06-11-2018 04:02 PM - edited 06-11-2018 04:04 PM
@jfalesi wrote:
@crossrulz2) I started on this project by inheriting code that used local variables all over the place. There was a bug that caused previous values to be used after some variables were updated, I researched the problem (probably on NI forums or StackOverflow), and I traced it to the use of local variables. Value properties were the proposed solution, so now I use them instead... Live, learn, un-learn, re-learn, repeat 😄
Value properties do not solve the problem of race conditions per se in comparison to local variables. It could be that the use of value properties can seem to solve it if you use the error cluster from them and in that way force a specific serialization of execution. But that is really driving out the devil with beelzebub, but not a solution.
Unnecessary serialization of code execution also degrades the performance even more than the Value property in itself already does.
06-11-2018 05:49 PM
@jfalesi wrote:There was a bug that caused previous values to be used after some variables were updated, I researched the problem (probably on NI forums or StackOverflow), and I traced it to the use of local variables. Value properties were the proposed solution, so now I use them instead... Live, learn, un-learn, re-learn, repeat 😄
That is actually my pet peeve #1. The value property node has the same issues as the local variable (race conditions like you described), but the property node is 1000s of times slower, as I already explained.
My #2 pet peeve is the simple Get/Set Action Engine, what I refer to as a Functional Global Variable. These are functionally the same as a Global Variable, but slower and more work to put together. A Look At Race Conditions
06-11-2018 06:00 PM
@crossrulz wrote:
@jfalesi wrote:There was a bug that caused previous values to be used after some variables were updated, I researched the problem (probably on NI forums or StackOverflow), and I traced it to the use of local variables. Value properties were the proposed solution, so now I use them instead... Live, learn, un-learn, re-learn, repeat 😄
That is actually my pet peeve #1. The value property node has the same issues as the local variable (race conditions like you described), but the property node is 1000s of times slower, as I already explained.
My #2 pet peeve is the simple Get/Set Action Engine, what I refer to as a Functional Global Variable. These are functionally the same as a Global Variable, but slower and more work to put together. A Look At Race Conditions
#2 is a "modern" pet peeve, isn't it? I think that in LV 2 that was your global?
06-12-2018 02:33 AM
@crossrulz wrote:
@jfalesi wrote:There was a bug that caused previous values to be used after some variables were updated, I researched the problem (probably on NI forums or StackOverflow), and I traced it to the use of local variables. Value properties were the proposed solution, so now I use them instead... Live, learn, un-learn, re-learn, repeat 😄
That is actually my pet peeve #1. The value property node has the same issues as the local variable (race conditions like you described), but the property node is 1000s of times slower, as I already explained.
I tested one update of 400 doubles by property node. It takes 40 ms. Calculating a random value for each of those 400 values takes 80 ms. No reason for me to force my design to use locals.
Of course if you do update by reference in bulk, turning defer panel updates on (and off when done) might speed it up. That will bring it back to 30 ms.
But if you test this in a for loop, lets say 1000 times, it will a long long time, since there will be noticeable synchronization with the refresh rate of the screen. This synchronization is actually forced by the defer panel update set to true. So the defer panel updates might help, or cause serious delay (LabVIEW is so much fun).
If the values did not change, updating by value property takes almost no time (<1m for 400 updates). Jet another think to consider.
I didn't test updating 400 values through local variables.
Normally, I don't worry about it. Handling controls by reference usually better suits my design, so I use that. Optimize (only) when needed.
I don't want to update 400 variables through local variables. 400 is a stretch, but 50 happens. Still don't want to do that through local variables.
06-12-2018 04:27 AM
Beside wires, local variables, property nodes etc., there is another option could be considered, the "Set/Get Control values by Reference". This method is said to be fast, but I do not really use it personally (most often I am lucky and I have limited number of indicators/controls, so I just use wires; or try to go for Arrays/clusters in order to limit the number of FP/BD objects).
Here is an example of this technique: