[msm] Why does it take so many bytes to represent a state machine?
Hi,
I'm using msm to store the state of many small objects. Each one is around
24 bytes on its own. However, I just found out from experimentation that a
MSM state machine takes many bytes to store. For the following program, the
print out is:
entering: State1
104
48
This indicates that the very simple one-state, no-transition, machine is
104 bytes, and takes 48 bytes even to serialized. The
front::state_machine_def, however, is only 1 byte, though I suspect thet
real state is stored only in the 104-byte back::state_machine.
Even the SimpleTutorial.cpp example, when I adapt it to print the size,
shows 128 bytes.
Theoretically, all this information take no more than a few bits to store,
and one byte is generous. What's the internal representation of a state
machine and how can I optimize the size of the representation? This matters
for my use case because I have many small objects for which I want to
maintain state, that are only ~20 bytes each. I thought perhaps I could
mitigate this size problem by storing the serialized bytes but even the
serialized bytes are many.
I'm using boost 1.51 and gcc 4.7.2 on 64-bit Linux.
Josh
#include <iostream>
#include <strstream>
#include
Hi,
I'm using msm to store the state of many small objects. Each one is around 24 bytes on its own. However, I just found out
from experimentation that a MSM state machine takes many bytes to store. For the following program, the print out is:
entering: State1
104
48
This indicates that the very simple one-state, no-transition, machine is 104 bytes, and takes 48 bytes even to serialized.
The front::state_machine_def, however, is only 1 byte, though I suspect thet real state is stored only
in the 104-byte back::state_machine.
Hi Josh, It depends on several factors: - MSM creates all the states at state machine creation and the states live until the state machine is destroyed, so even if the states have no data, it'll be a byte per state. - you need to keep the id of the current state in each region (int) - 2 bool for internal implementation details - a queue for deferred events if you have some in your fsm (if none, MSM will deactivate this, but you'll still pay 1 byte). - an event queue (enabled by default but you can deactivate it if not needed (see http://svn.boost.org/svn/boost/trunk/libs/msm/doc/HTML/ch03s02.html#d0e1139) but it will still cost 1 byte. Both queues are per default a std::deque, which can be expensive on some systems. You can choose another container if you wish (see http://svn.boost.org/svn/boost/trunk/libs/msm/doc/HTML/ch03s05.html#d0e2680). As you see, if you remove the queues, there is not much more to take away. Also note that a text archive brings its own costs. HTH, Christophe
Thanks for the quick response and thanks for making this handy library. I turned off message queueing (typedef int no_message_queue) and I'm down to 20 bytes, much better, though still with some unaccounted bytes. I'm looking for a better way. I don't use any attributes, except for event attributes, or submachines. I also don't care about event/state history. This means the only state-related info is the state ID. What about just reading and storing the state ID, and using the stored ID to restore the state next time I need to process an event? I know how to get state ID (current_state()), but how do I set state from ID? Josh On Tue, Nov 13, 2012 at 3:52 PM, Christophe Henry < christophe.j.henry@googlemail.com> wrote:
**
*>*Hi,
I'm using msm to store the state of many small objects. Each one is
around 24 bytes on its own. However, I just found out
from experimentation that a MSM state machine takes many bytes to store. For the following program, the print out is:
entering: State1
104
48
This indicates that the very simple one-state, no-transition, machine is 104 bytes, and takes 48 bytes even to serialized.
The front::state_machine_def, however, is only 1 byte, though I suspect thet real state is stored only
in the 104-byte back::state_machine.
Hi Josh,
It depends on several factors:
- MSM creates all the states at state machine creation and the states live until the state machine is destroyed, so even if the states have no data, it'll be a byte per state.
- you need to keep the id of the current state in each region (int)
- 2 bool for internal implementation details
- a queue for deferred events if you have some in your fsm (if none, MSM will deactivate this, but you'll still pay 1 byte).
- an event queue (enabled by default but you can deactivate it if not needed (see http://svn.boost.org/svn/boost/trunk/libs/msm/doc/HTML/ch03s02.html#d0e1139) but it will still cost 1 byte. Both queues are per default a std::deque, which can be expensive on some systems. You can choose another container if you wish (see http://svn.boost.org/svn/boost/trunk/libs/msm/doc/HTML/ch03s05.html#d0e2680 ).
As you see, if you remove the queues, there is not much more to take away.
Also note that a text archive brings its own costs.
HTH,
Christophe
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Thanks for the quick response and thanks for making this handy library.
I turned off message queueing (typedef int no_message_queue) and I'm down to 20 bytes, much better, though still with some unaccounted bytes. I'm looking for a better way.
I don't use any attributes, except for event attributes, or submachines. I also don't care about event/state history.
Event attributes have no memory cost on your state machine. History costs the same as the id (an int per region).
This means the only state-related info is the state ID. What about just reading and storing the state ID, and using the stored ID to restore the state next time I need to process an event? I know how to get state ID (current_state()), but how do I set state from ID?
You cannot set the state, MSM handles the lifecycle of its states.
Josh
MSM just stores the id of the current state(s) in order to call on_entry/on_exit or for bookkeeping. MSM does not recreate the active states after each transition but insteads keeps them alive for performance reasons. This also allows you to store data in states (you need this quite often). I don't know how many bytes still are needed for your text archive, you should ask this to Robert Ramey. Christophe
If it can be shrunk to the size of an int for the stripped-down use case, for storing the state ID, which is what's really needed in principle, it would be nice, but I think a 20-byte overhead is not a show-stopper for me for now. On Tue, Nov 13, 2012 at 4:31 PM, Christophe Henry < christophe.j.henry@googlemail.com> wrote:
**
Thanks for the quick response and thanks for making this handy library.
I turned off message queueing (typedef int no_message_queue) and I'm down to 20 bytes, much better, though still with some unaccounted bytes. I'm looking for a better way.
I don't use any attributes, except for event attributes, or submachines. I also don't care about event/state history.
Event attributes have no memory cost on your state machine. History costs the same as the id (an int per region).
This means the only state-related info is the state ID. What about just reading and storing the state ID, and using the stored ID to restore the state next time I need to process an event? I know how to get state ID (current_state()), but how do I set state from ID?
You cannot set the state, MSM handles the lifecycle of its states.
Josh
MSM just stores the id of the current state(s) in order to call on_entry/on_exit or for bookkeeping. MSM does not recreate the active states after each transition but insteads keeps them alive for performance reasons. This also allows you to store data in states (you need this quite often). I don't know how many bytes still are needed for your text archive, you should ask this to Robert Ramey.
Christophe
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (2)
-
Christophe Henry
-
☂Josh Chia (谢任中)