Aumenta Statechart vs. Meta State Machine


142

Apparentemente boost contiene due librerie separate per macchine a stati: Statechart e Meta State Machine (MSM). Le tagline forniscono descrizioni molto simili:

  • Boost.Statechart - Le macchine a stati finiti arbitrariamente complesse possono essere implementate in codice C ++ facilmente leggibile e gestibile.
  • Meta State Machine - Una libreria ad altissime prestazioni per macchine espressive a stati finiti UML2.

Sai quali sono le differenze chiave e quali sono le considerazioni nella scelta tra i due?


4
Hehe, un altro caso di grande interesse ma nessuno conosce la risposta ... :)
j_random_hacker

8
: D Questa domanda è l'apice della mia esperienza SO! Ricevi risposte da entrambi gli sviluppatori ... può andare meglio ?! Mille grazie a Christophe e Andreas.
FireAphis l'

Ottima domanda e sei riuscito a ottenere le risposte dei due sviluppatori concorrenti!
Offirmo,

3
Statechart ti fa mettere funzionalità in costruttori e distruttori. Questo è un anti-schema, specialmente con i distruttori.
Lev,

2
In Statechart, le azioni di uscita possono essere inserite in un gestore exit () separato che viene chiamato prima della distruzione. Penso che questa disposizione mitiga il problema principale con l'anti-schema menzionato da Lev.
Tim Crews

Risposte:


116

Poiché sembra esserci molto interesse, permettimi di esprimere la mia opinione (ovviamente di parte), che dovrebbe quindi essere presa con un granello di sale:

  • MSM è molto più veloce
  • MSM non richiede RTTI o qualcosa di virtuale
  • MSM ha un supporto UML2 più completo (ad esempio transizioni interne, regioni ortogonali conformi a UML)
  • MSM offre un linguaggio descrittivo (in realtà diversi). Ad esempio, utilizzando il front-end eUML, una transizione può essere descritta come Origine + Evento [Guard] / Azione == Target
  • MSM farà soffrire il tuo compilatore per macchine a stati più grandi, quindi avrai bisogno di un compilatore piuttosto recente (g ++> = 4.x, VC> = 9)

Puoi farti un'opinione migliore cercando i commenti postati durante la revisione di MSM. Questo argomento è stato molto discusso nell'elenco degli sviluppatori.


2
Grazie mille. È un piacere ascoltare l'opinione dello sviluppatore stesso! Ora abbiamo solo bisogno della risposta di Andreas Huber :)
FireAphis,

16
Min-nit-pick: in modalità di rilascio, l'uso di C ++ RTTI (dynamic_cast, typeid) è strettamente facoltativo con Boost.Statechart.

111

Come già menzionato Christophe, una delle differenze chiave tra le due librerie è la prestazione di runtime. Mentre MSM offre probabilmente il meglio che puoi ottenere qui, Statechart scambia consapevolmente i cicli di memoria e processore verso una migliore scalabilità.

Con Boost.Statechart puoi distribuire il layout (cioè stati, transizioni) della tua macchina a stati su più unità di traduzione (file cpp) in modi impossibili con MSM. Ciò consente di rendere più gestibile l'implementazione di grandi FSM e di ottenere una compilazione molto più veloce rispetto a MSM.

Se il sovraccarico prestazionale di Statechart rispetto a MSM sarà effettivamente significativo per la tua applicazione è spesso abbastanza facile rispondere quando ti chiedi quanti eventi la tua app dovrà elaborare al secondo.

Supponendo un FSM moderatamente complesso implementato con Boost.Statechart, ecco alcuni numeri di palla:

  • La maggior parte degli hardware per PC attuali gestirà facilmente> 100.000 eventi al secondo
  • Anche hardware con risorse molto limitate sarà in grado di elaborare alcune centinaia di eventi al secondo.

Per quanto riguarda il carico della CPU, se il numero di eventi da elaborare è molto più basso di questi numeri, il sovraccarico di Boost.Statechart rispetto a MSM non sarà quasi certamente evidente. Se il numero è molto più alto, stai decisamente meglio con MSM.

Informazioni più approfondite sui compromessi di prestazioni / scalabilità sono disponibili qui: http://www.boost.org/doc/libs/1_45_0/libs/statechart/doc/performance.html


9
Ciao Andreas, riguardo alla diffusione del layout, ci sono stati alcuni miglioramenti. Ora puoi compilare sottomarini su diversi core. Non è perfetto ma è un notevole miglioramento. Vedi svn.boost.org/svn/boost/trunk/libs/msm/doc/HTML/…
Christophe Henry,

11

Durante la codifica della mia implementazione PPP ho usato Statechart per tre motivi: 1) Statechart è più semplice e ha una documentazione più chiara; 2) Non mi piace davvero UML :)

I documenti di Boost affermano che MSM è almeno 20 volte più veloce, ma si compila piuttosto lentamente per FSM di grandi dimensioni.


7
Mentre sono d'accordo sul fatto che gran parte di UML sono i nuovi vestiti degli imperatori, le carte di stato sono l'unica cosa che ha effettivamente valore in UML.
Jon Trauntvein,

4
Sicuramente, ma ho imparato statechart dalla matematica discreta, non dall'ingegneria del software. Questo lascia un segno :)
fiammata il

4

Qualche tempo fa ho iniziato con Statechart e sono passato a MSM perché era più facile da usare in combinazione con asio da un singolo thread. Non sono riuscito a combinare Statechart e le sue capacità di multithreading con il mio uso di asio - è stato probabilmente una sorta di incomprensione per principianti di Statechart da parte mia. Ho scoperto che MSM era più facile da usare in quanto non riguardava il multithreading.


1
La maggior parte dei tipi di statechart non affronta neanche il threading. Per quanto riguarda il multithreading, dovresti essere in grado di utilizzare boost :: statechart :: state_machine proprio come la controparte MSM. boost :: statechart :: asynchronous_state_machine e i tipi associati sono una parte strettamente facoltativa della libreria di statechart.

2

In risposta all'entrata tardiva di Tim alla discussione (che affronta anche uno dei primi commenti di Lev).

Come uno di quelli che hanno sostenuto la separazione dell'uscita dai distruttori nello statechart (argomento basato su un caso d'uso reale, sull'interazione con il mondo reale, ad es. I / O), quando è stato presentato a Boost, sono d'accordo che ci possono essere problemi nel mettere l'uscita logica nei distruttori. David Abrahams ha fatto sorprendentemente argomentazioni convincenti anche sulla sicurezza delle eccezioni. Per questi motivi, Statechart non richiede di inserire la logica nei distruttori, ma consente di farlo con i soliti consigli.

La logica che dovrebbe sempre essere eseguita come parte di una transizione da uno stato (non la distruzione dell'oggetto statechart nel suo insieme) può (e dovrebbe se c'è anche una pulizia delle risorse da fare) essere separata in un'azione exit () separata.

Per uno stato "sottile" senza stato attivo (risorse), solo azioni di entrata / uscita da eseguire, è possibile eseguire quelle azioni in ctor e d'tor e assicurarsi che il costruttore e il distruttore non lancino. Non c'è motivo per loro - non c'è stato su cui eseguire RAII - non c'è male nel far sì che la gestione degli errori in questi luoghi generi eventi appropriati. Potrebbe comunque essere necessario considerare se si desidera che le azioni di uscita che modificano lo stato esterno vengano eseguite alla distruzione della macchina a stati ... e metterle in azione di uscita se non si desidera che si verifichino in questo caso ...

Statechart modella l'attivazione come istanziazione di un oggetto, quindi se il tuo costruttore ha un vero lavoro / attivazione / istanza da fare e se è in grado di fallire in modo tale che lo stato non possa essere inserito Statechart lo supporta dandoti la possibilità di mappare un'eccezione a un evento. Questo viene gestito in un modo che elabora la gerarchia di stato alla ricerca di uno stato esterno che gestisca l'evento di eccezione, analogo al modo in cui lo stack si sarebbe svolto per un modello di chiamata basato sullo stack di chiamate.

Tutto questo è ben documentato - ti suggerisco di leggere i documenti e provarlo. Ti suggerisco di utilizzare i distruttori per ripulire le "risorse software" e uscire dalle azioni per eseguire "azioni di uscita nel mondo reale".

Vale la pena notare che la propagazione delle eccezioni è un po 'un problema in tutti gli ambienti guidati da eventi, non solo negli statechart. È meglio ragionare e includere guasti / errori nella progettazione del proprio statechart e se e solo se non è possibile gestirli in un altro modo ricorrere alla mappatura delle eccezioni. Almeno per me funziona - ymmmv ....


Grazie, vedo che tutte le mie preoccupazioni sono sufficientemente risolte nella parte "Gestione delle eccezioni" del tutorial Boost :: statechart. In tal caso, penso che il commento di Lev (fuorviante) possa essere indirizzato semplicemente indicando la sezione "uscita a due stadi" di quel tutorial. Prenderei in considerazione l'eliminazione della mia risposta, tranne per il fatto che la tua risposta aggiunge informazioni preziose a questo argomento.
Tim Crews
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.