02-14-2012 12:26 PM
Ummmm. OK. I guess... Yeah.
02-14-2012 12:34 PM
@Steve Chandler wrote:
Inside the state machine there is an array of a cluter containing an array of states that I will call "instructions". Each instruction is an array of states. These are what I am trying to decide on using an enum or a string for. The instructions array is loaded into a shift register on initialization. The contents of this array never changes inside the state machine.
There is a state called "load instruction" that takes an integer input from outside this VI which indexes the "instructions" array, unbundles the array of states, and loads that array into another shift register. It sets an integer shift register that I will call "instruction step counter" to zero. The state machine iterates through the array of states by incrementing the instruction step counter and indexing the next step. The final step in each instruction is the load instruction state and the cycle continues.
Weird enough?
A few thoughts for you to ponder because I would look at this differently.
There is a state called "load instruction" that takes an integer input from outside this VI which indexes the "instructions" array, unbundles the array of states, and loads that array into another shift register
Sounds like a named queue and the "load instruction" state is more properly in the scope of the executive calling the shots rather than the worker bee (SM) whose poorly managed.
02-14-2012 01:46 PM
@JÞB wrote:
A few thoughts for you to ponder because I would look at this differently.
There is a state called "load instruction" that takes an integer input from outside this VI which indexes the "instructions" array, unbundles the array of states, and loads that array into another shift register
Sounds like a named queue and the "load instruction" state is more properly in the scope of the executive calling the shots rather than the worker bee (SM) whose poorly managed.
The architecture might seem a little strange but it is totally about performance. Also the architecture is pretty well cast in stone. I literally cannot change it. That is outside my control.
02-14-2012 02:40 PM
well we've all been there before (do it like this but make it work)
from raw performance an array of clusters of equal size will index much easier. if the string is the only variable sized element in the cluster I would expect performance to improve by swapping it to a enum.
But I haven't benchmarked it either.
As far as readability and write ability the case select tool does sound like a nice aid. You can get some simillar benefits by using separators in the enum by adding dash and dash-dash and dash-dash-dash but that if far from ideal if you get a whole lot of cases. (silly enum items editor does not support everything an enum can do)
02-14-2012 03:20 PM
I doubt the unbundles will hurt your performance. The compiler should take care of that for you and you should end up with the code under the hood doing a direct access to the desired data.
02-14-2012 03:24 PM - edited 02-14-2012 03:34 PM
I did a quick benchmark and the enum wins as suspected. I attached the project in LV82 format but the numbers below are from running under LabVIEW 2011.
These numbers are how long in seconds it takes for 10 million calls to the different types of state machines. I also tested each with and without subroutine priority. The enum set for normal priority beats the string version running as a subroutine.
However I found another disadvantage in using the enums. If you have an array of enums constant it defaults to some particular width. You can resize the array elements so that you can see everything but as soon as you edit the typedef the width goes back to the default. Even if the typedef is strict and even if the array of the typedef is also a typedef.
Regardless of that the performance of an enum is so much better that I will have to live with these issues.
[Edit: I didn't mention that I am redoing this application. I started out with a nice object oriented approach. I was using the command pattern with dynamic dispatching selecting the states. Performance was absolutely aweful. I didn't mess around too much with changing accessors to be inline, turning off debugging, or changing the execution priority of the methods. There were just too many files to be keeping up with.]
02-14-2012 04:53 PM - edited 02-14-2012 04:53 PM
Thanks for the benchmark, Steve. I have always been interested in it but never took the time to investigate. As a rule of thumb, I take from your benchmark that enums are about 2 times faster than strings.
On my computer (running LabVIEW 2010 SP1) enums and strings are not that much apart as on yours. Here is what I see:
02-14-2012 05:24 PM
well the good news is my machine is about 7-10% faster than Steves- right across the board nicely consistant with his numbers.
whatch the normal priority vis in the attachment- debugging was inadvertantly turned back on (for a 2x performance hit)
02-14-2012 06:36 PM
You can still squeeze that last bit of performance out of your state machine!
02-14-2012 06:48 PM
Ouch! Kind of reminds me of this