mirror of
https://github.com/boostorg/msm.git
synced 2026-02-19 14:32:34 +00:00
69 lines
12 KiB
HTML
69 lines
12 KiB
HTML
<html><head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
|
<title>Performance / Compilers</title><meta name="generator" content="DocBook XSL-NS Stylesheets V1.75.2"><link rel="home" href="index.html" title="Meta State Machine (MSM)"><link rel="up" href="index.html" title="Meta State Machine (MSM)"><link rel="prev" href="ar01s04.html" title="User's Guide"><link rel="next" href="ar01s06.html" title="Questions & Answers"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center"> Performance / Compilers</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ar01s04.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="ar01s06.html">Next</a></td></tr></table><hr></div><div class="sect1" title="Performance / Compilers"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d0e3639"></a> Performance / Compilers</h2></div></div></div><p>Tests were made on different PCs running Windows XP and Vista and compiled with VC9
|
|
SP1 or Ubuntu and compiled with g++ 4.2 and 4.3. For these tests, the same player state
|
|
machine was written using Boost.Statechart, as a <a class="link" href="examples/SC Simple.cpp" target="_top">state machine with only simple states</a> and
|
|
as a <a class="link" href="examples/SC Composite.cpp" target="_top">state machine with a composite
|
|
state</a>. The same simple and composite state machines are implemented with MSM
|
|
with a standard frontend <a class="link" href="examples/MsmSimple.cpp" target="_top">(simple)</a><a class="link" href="examples/MsmComposite.cpp" target="_top">(composite)</a>, the simple one also with
|
|
<a class="link" href="examples/MsmSimpleFunctors.cpp" target="_top">functors</a> and with <a class="link" href="examples/EumlSimple.cpp" target="_top">eUML</a>. As these simple machines need no
|
|
terminate/interrupt states, no message queue and have no-throw guarantee on their
|
|
actions, the MSM state machines are defined with minimum functionality.</p><div class="sect2" title="Speed"><div class="titlepage"><div><div><h3 class="title"><a name="d0e3661"></a>Speed</h3></div></div></div><p>VC9:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>The simple test completes 36 times faster with Msm than with
|
|
Boost.Statechart</p></li><li class="listitem"><p>The composite test completes 18 times faster with MSM</p></li><li class="listitem"><p>The fastest version is with eUML/functors. It completes 58 times
|
|
faster than Boost.Statechart. A transition costs 4.5ns on a
|
|
Q6600.</p></li></ul></div><p>gcc 4.2.3:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>The simple test completes 54 times faster with Msm (with
|
|
functors)</p></li><li class="listitem"><p>The composite test completes 25 times faster with Msm</p></li></ul></div></div><div class="sect2" title="Executable size"><div class="titlepage"><div><div><h3 class="title"><a name="d0e3685"></a>Executable size</h3></div></div></div><p>There are some worries that MSM generates huge code. Is it true? The 2 compilers I
|
|
tested disagree with this claim. On VC9, the test state machines used in the
|
|
performance section produce executables of 14kB (for simple and eUML) and 21kB (for
|
|
the composite). This includes the test code and iostreams. By comparison, an empty
|
|
executable with iostreams generated by VC9 has a size of 7kB. Boost.Statechart
|
|
generates executables of 43kB and 54kB. As a bonus, eUML comes for “free” in terms
|
|
of executable size. You even get a speed gain. With g++ 4.3, it strongly depends on
|
|
the compiler options (much more than VC). A good size state machine with –O3 can
|
|
generate an executable of 600kB, and with eUML you can get to 1.5MB. Trying with –Os
|
|
–s I come down to 18kB and 30kB for the test state machines, while eUML will go down
|
|
to 1MB (which is still big), so in this case eUML does not come for free.</p></div><div class="sect2" title="Supported compilers"><div class="titlepage"><div><div><h3 class="title"><a name="d0e3690"></a>Supported compilers</h3></div></div></div><p> MSM was successfully tested with: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>VC8 (please read further), VC9SP1, VC10 Beta 1 and 2</p></li><li class="listitem"><p>g++ 4.1 and higher</p></li><li class="listitem"><p>Green Hills Software MULTI for ARM v5.0.5 patch 4416 (Simple and
|
|
Composite tutorials)</p></li></ul></div><p> eUML will only work with: </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>VC8 (partly). You cannot, however use any overloaded function (like
|
|
splice) and compile times and RAM consumption explode</p></li><li class="listitem"><p>VC9SP1, VC10 Beta1-2</p></li><li class="listitem"><p>g++ 4.3 and higher (previous versions lack native typeof
|
|
support)</p></li></ul></div><p>VC8 and to some lesser extent VC9 suffer from a bug. Enabling the option "Enable
|
|
Minimal Rebuild" (/Gm) will cause much higher compile-time (up to three times with
|
|
VC8!). This option being activated per default in Debug mode, this can be a big
|
|
problem.</p></div><div class="sect2" title="Limitations"><div class="titlepage"><div><div><h3 class="title"><a name="d0e3719"></a> Limitations </h3></div></div></div><p>
|
|
</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>Compilation times of state machines with > 80 transitions that are
|
|
going to make you storm the CFO's office and make sure you get a shiny
|
|
octocore with 8GB RAM by next week, unless he's interested in paying you
|
|
watch the compiler agonize for hours... (Make sure you ask for dual 24"
|
|
as well, it doesn't hurt).</p></li><li class="listitem"><p>eUML allows very long constructs but will also quickly increase your
|
|
compile time on some compilers (VC9, VC10 Beta1) with buggy decltype
|
|
support (I suspect some at least quadratic algorithms there). Even g++
|
|
4.4 shows some regression compared to 4.3 and will crash if the
|
|
constructs become too big.</p></li><li class="listitem"><p>Need to overwrite the mpl::vector/list default-size-limit of 20 and
|
|
fusion default vector size of 10 if more than 10 states found in a state
|
|
machine</p></li></ul></div><p>
|
|
</p></div><div class="sect2" title="Compilers corner"><div class="titlepage"><div><div><h3 class="title"><a name="d0e3735"></a> Compilers corner </h3></div></div></div><p>Compilers are sometimes full of surprises and such strange errors happened in the
|
|
course of the development that I wanted to list the most fun for readers’
|
|
entertainment.</p><p><span class="underline">VC8</span>: </p><p><code class="code">template <class StateType> </code></p><p><code class="code">typename ::boost::enable_if< </code></p><p><code class="code">typename ::boost::mpl::and_<</code></p><p><code class="code">typename ::boost::mpl::not_<typename
|
|
has_exit_pseudo_states<StateType>::type>::type, </code></p><p><code class="code">typename ::boost::mpl::not_<typename
|
|
is_pseudo_exit<StateType>::type>::type >::type,BaseState*>::type
|
|
</code></p><p>I get the following error:</p><p>error C2770: invalid explicit template argument(s) for '`global
|
|
namespace'::boost::enable_if<is_pseudo_exit<StateType>::type,BaseState*>::type
|
|
boost::msm::state_machine<Derived,HistoryPolicy,BaseState>::add_state<ContainingSM>::new_state_helper(boost::msm::dummy<__formal>)
|
|
const' </p><p>If I now remove the first “::” in ::boost::mpl , the compiler shuts up. So in this
|
|
case, it is not possible to follow Boost’s guidelines.</p><p><span class="underline">VC9</span>:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>This one is my all times’ favorite. Do you know why the exit pseudo
|
|
states are referenced in the transition table with a
|
|
“submachine::exit_pt” ? Because “exit” will crash the compiler. “Exit”
|
|
is not possible either because it will crash the compiler on one
|
|
machine, but not on another (the compiler was installed from the same
|
|
disk).</p></li><li class="listitem"><p>Sometimes, removing a policy crashes the compiler, so some versions
|
|
are defining a dummy policy called WorkaroundVC9.</p></li><li class="listitem"><p>Typeof: While g++ and VC9 compile “standard” state machines in
|
|
comparable times, Typeof (while in both ways natively supported) seems
|
|
to behave in a quadratic complexity with VC9 and VC10.</p></li><li class="listitem"><p>eUML: in case of a compiler crash, changing the order of state
|
|
definitions (first states without entry or exit) sometimes solves the
|
|
problem.</p></li></ul></div><p><span class="underline">g++ 4.x</span>: Boring compiler, almost all is
|
|
working almost as expected. Being not a language lawyer I am unsure about the
|
|
following “Typeof problem”. VC9 and g++ disagree on the question if you can derive
|
|
from the BOOST_TYPEOF generated type without first defining a typedef. I will be
|
|
thankful for an answer on this. I only found two ways to break the compiler:</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>Add more eUML constructs until something explodes (especially with
|
|
g++-4.4) </p></li><li class="listitem"><p>The build_terminate function uses 2 mpl::push_back instead of
|
|
mpl::insert_range because g++ would not accept insert_range.</p></li></ul></div><p>You can test your compiler’s decltype implementation with the <a class="link" href="examples/CompilerStressTestEuml.cpp" target="_top">following stress test</a>
|
|
and reactivate the commented-out code until the compiler crashes.</p></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ar01s04.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="ar01s06.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">User's Guide </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Questions & Answers</td></tr></table></div></body></html> |