
AMDG Andrey Semashev wrote:
Hello,
I've updated the Boost.FSM library in the Vault with the following changes: - Several threading issues pointed out by Steven Watanabe were fixed. - Some minor optimizations added to reduce the amount of generated code and possibly speed up compilation a little. - Exception classes are now exposed with default visibility on GCC 4.0 and later under Linux. I'm not sure if other compilers/platforms need this and have support for similar feature. - A new example "BitMachine" added. It is quite similar to same-named example of Boost.Statechart and may be used as a performance test. - The Performance section of the docs updated with some test results.
First of all I think that the elapsed time is more useful than the number of iterations per second. I know that one is just the inverse of the other but the elapsed time has a linear correlation to the amount of work being done. Second, ~half the time taken for the benchmark is the overhead of the test itself rather than the actual state machine. Try this version. #include <boost/mpl/for_each.hpp> #include <boost/mpl/range_c.hpp> //! Function Object version for MPL for_each struct invoke_sm_func { typedef void result_type; invoke_sm_func(BitFSM_t& bfsm) : fsm(&bfsm) { } template<class Index> void operator()(Index) { invoke_sm<Index::value>(*fsm); } BitFSM_t* fsm; }; //! Performance test implementation void run_performance_test(BitFSM_t& fsm) { //... // Execute performance loop for (register unsigned long i = 0, end = (unsigned long)(NO_OF_PERFORMANCE_EVENTS / NO_OF_BITS); i < end; ++i) { boost::mpl::for_each<boost::mpl::range_c<int, 0, NO_OF_BITS>
(invoke_sm_func(fsm)); } //handle the remainder typedef boost::mpl::range_c<int, 0, (NO_OF_PERFORMANCE_EVENTS % NO_OF_BITS)> tail; boost::mpl::for_each<tail>(invoke_sm_func(fsm));
//... } Instead of using MPL vector/list you can create your own MPL sequence. struct StatesList_t { struct tag {}; template<unsigned int N> struct iterator { typedef BitState<N> type; typedef iterator<N + 1> next; }; typedef iterator<0> begin; typedef iterator<(1 << NO_OF_BITS)> end; }; enum { NO_OF_STATES = (1 << NO_OF_BITS) }; In this case trying to reuse code actually generates more work both for yourself and for the compiler. In Christ, Steven Watanabe