03-12-2011 10:02 PM
Is it possible to benchmark the transmit times of local variables?
I've run some simple benchmark stuff before, but never something that would figure out how long it took to get a piece of data through a local variable.
I've attached a simple program that sends some info through a local variable, and there's obviously some lag that's visable, well, at least visable on the system I'm running. I know that lag depends on the system the program is running on so I'd really like to find a way to test it on the various PC's that we use here.
Any ideas?
-Ian
Solved! Go to Solution.
03-12-2011 10:31 PM
I really don't understand your question at all. Local Variables are not a means of "transmission". And I don't understand how your VI is benchmarking whatever it is you are trying to do.
They are a copy of the data that is present in a front panel control or indicator. Their time of execution is much quicker than using a value property node. But not as quick as using wires and the control terminal.
If you want to send data from one loop to another, you should be looking at queues or notifiers.
03-12-2011 10:51 PM
You're right, the attached program doesn't benchmark anything. If you run the program with the attached test.txt file in the path, you'll be able to watch data move from one loop to the other by the use of local variables. On my machine there is a noticable lag between the time that the indicator in the writing loop updates and the indicator in the reading loop updates. When I say noticable I'm thinking it's in the realm of under 250ms. Not a large lag, however, on some of our machines this lag could be more, even enough to cause issues with the way the .vi operates.
Some applications can't always use queues or notifiers to accomplish certain requirements, local variables aren't the devil are they? If they were really that bad I can't imagine the folks at NI keeping them in LabVIEW.
-Ian
03-12-2011 11:26 PM
No, they aren't the devil as long as you are aware of their capabilities and their limits.
As for "some applications can't always use queues or notifiers to accomplish certain requirements", give me one application where you can't use a queue or notifier, and I'll bet you can.
The probelm with your "benchmark" is that it is a poor test. You are doing a visual look at two parallel while loops that have no synchronization between them. If you used a wait until next msec in both loops, then you'd see better synchronization. Get the File Read out of the loop because that could be causing a random delay.
And the biggest concern with local variables is "race conditions". Search the forums for that to learn more about them. You can't control what piece of code executes in what order. If you have two parallel iterations of the two loops, whether the value gets written to the local variable before or after the local variable is read and written to the other indicator determines whether a new or old value is used. If it is an old value, it is going to be another iteration of the bottom loop before it gets updated.
Search the forums for local variables vs terminals vs. property nodes, and you'll see that local variables get updated on the order of milliseconds. The only reason you are seeing "in the realm of under 250ms" is because that is the iteration rate of your bottom loop.
03-12-2011 11:54 PM
What about a program that used a cDAQ to acquire the voltage input from a potentiometer that determines the location of a pulley inside an assembly. It then used that input as the "current value" input in a pid loop that output a command for pulse width modulation that's used for positioning that pulley. Now throw in the attached .vi that outputs a different "set point" to that PID loop every 10 minutes or so. The acquisition and PWM can be done in the same loop, but if I rewrote the attached .vi with queues and dequeued the updated setpoint into the input/output loop wouldn't it hold the I/O loop up waiting for the queue to have something dumped into it? The loop that you're dequeing information into will not iterate until there's something in the queue, correct? So wouldn't that be a case where it would make more sense to use a variable? I know about race conditions, but in that case you're only writing in one place and reading it in another. Yes, there's some architectural artistic licensing of the dataflow going on, but you're not causing race conditions at that point?
Correct me if I'm not understanding something, or mistating it. I've been known to be dense before.
-Ian
03-13-2011 12:45 AM
Dequeue functions have a timeout input. So the loop iteration can proceed even if a new element hasn't arrived in the queue.
If you need a variable, a functional global variable or action engine would be better.
A local variable can be used, as long as you realize the syncronization of the loops and the possibility of the race condition between reading and writing of the local variable may prevent you from getting the new data immediately. It's not the local variable that is slow, it is everything else about the architecture. Now a delay of a fraction of a second is probably no big deal when you are talking about a time scale of 10 minutes. But the example VI you created is not the same thing and was trying to test instantaneous transfer of data from one loop to the other when the architecture using local variables is flawed.
03-13-2011 09:30 AM
Okay, point taken, bad example.
So I rewrote the above, albiet bad, example using queues and a timeout on the dequeue so as to not interupt other processes in that loop. However, if the dequeue times out it changes the indicators in that loop to a 0 instead of just leaving them alone. How can you rewrite this without having that unwanted side effect?
-Ian
03-13-2011 09:58 AM
I cannot open your VI from home, but in general you put a case structure after the Dequeue function. Connect the Timed Out? boolean output of the Dequeue to the selector of the case structure. In the True case (Dequeue timed out) just wire the previous data straight through. In the False case wire the Dequeue data output to the right side tunnel. Of course you need to have the data on a shift register to retain the value from the previous valid Dequeue.
Lynn
03-13-2011 10:17 AM
I guess using functional globals in the lower loop works like the attached. However, at this point isn't it less cluttered, cumbersome and easier all around to have just used local variables from the get-go?
Or is there an easier way to accomplish this that I'm missing?
-Ian
03-13-2011 05:28 PM
Sure there's an easier way, you could just put the indicators in the upper loop. 😄
/Y