wake-up-neo.com

Boost Statechart vs. Meta State Machine

Anscheinend enthält boost zwei separate Bibliotheken für Zustandsmaschinen: Statechart und Meta State Machine (MSM). Die Slogans geben sehr ähnliche Beschreibungen:

  • Boost.Statechart - Beliebig komplexe Zustandsautomaten können in leicht lesbaren und wartbaren C++ - Code implementiert werden.
  • Meta State Machine - Eine sehr leistungsfähige Bibliothek für ausdrucksstarke UML2-Zustandsautomaten.

Wissen Sie, was die Hauptunterschiede sind und welche Überlegungen es gibt, zwischen beiden zu wählen?

139
FireAphis

Gestatten Sie mir, da hier offenbar großes Interesse besteht, meine (offensichtlich voreingenommene) Meinung zu äußern, die daher mit einem Körnchen Salz aufgenommen werden sollte:

  • MSM ist viel schneller
  • MSM erfordert keine RTTI oder irgendetwas Virtuelles
  • MSM bietet eine umfassendere UML2-Unterstützung (z. B. interne Übergänge, UML-konforme orthogonale Bereiche).
  • MSM bietet eine beschreibende Sprache (tatsächlich mehrere). Unter Verwendung des eUML-Frontends kann ein Übergang beispielsweise als Quelle + Ereignis [Schutz]/Aktion == Ziel beschrieben werden
  • MSM wird Ihren Compiler unter größeren Zustandsautomaten leiden lassen, so dass Sie einen ziemlich aktuellen Compiler benötigen (g ++> = 4.x, VC> = 9)

Sie können sich eine bessere Meinung bilden, indem Sie nach Kommentaren suchen, die während der Überprüfung von MSM gepostet wurden. Dieses Thema wurde auf der Entwicklerliste viel diskutiert.

113

Wie Christophe bereits erwähnt hat, ist einer der Hauptunterschiede zwischen den beiden Bibliotheken die Laufzeitleistung. Während MSM wahrscheinlich das Beste bietet, das Sie hier bekommen können, handelt Statechart bewusst mit Speicher- und Prozessorzyklen, um eine bessere Skalierbarkeit zu erreichen.

Mit Boost.Statechart können Sie das Layout Ihrer Zustandsmaschine (dh Zustände, Übergänge) auf verschiedene Arten über mehrere Übersetzungseinheiten (CPP-Dateien) verteilen. ' t mit MSM. Auf diese Weise können Sie die Implementierung großer FSMs einfacher verwalten und schneller kompilieren als mit MSM.

Ob der Performance-Overhead von Statechart im Vergleich zu MSM tatsächlich für Ihre Anwendung von Bedeutung ist, lässt sich häufig leicht beantworten, wenn Sie sich fragen, wie viele Ereignisse Ihre App pro Sekunde verarbeiten muss.

Angenommen, ein mäßig komplexes FSM wurde mit Boost.Statechart implementiert. Hier einige Zahlen zum Baseballstadion:

  • Die meiste gegenwärtige PC-Hardware wird leicht mit> 100'000 Ereignissen pro Sekunde fertig
  • Selbst sehr ressourcenbeschränkte Hardware kann einige hundert Ereignisse pro Sekunde verarbeiten.

Wenn in Bezug auf die CPU-Auslastung die Anzahl der zu verarbeitenden Ereignisse viel geringer ist als diese Zahlen, ist der Boost.Statechart-Overhead im Vergleich zu MSM mit ziemlicher Sicherheit nicht spürbar. Wenn die Anzahl viel höher ist, sind Sie mit MSM definitiv besser dran.

Weitere Informationen zu den Kompromissen zwischen Leistung und Skalierbarkeit finden Sie hier: http://www.boost.org/doc/libs/1_45_0/libs/statechart/doc/performance.html

109
user49572

Bei der Programmierung meiner eigenen PPP Implementierung habe ich Statechart aus drei Gründen verwendet: 1) Statechart ist einfacher und hat eine klarere Dokumentation; 2) Ich mag UML wirklich nicht :)

Laut Boost-Docs ist MSM mindestens 20-mal schneller, für große FSMs ist die Kompilierung jedoch recht langsam.

10
blaze

Vor einiger Zeit habe ich mit Statechart begonnen und bin zu MSM gewechselt, weil es einfacher war, es in Verbindung mit Asio von einem einzelnen Thread aus zu verwenden. Ich habe es nicht geschafft, Statechart und seine Multithreading-Funktionen mit meiner Verwendung von Asio zu verknüpfen - es war wahrscheinlich eine Art Neuling, der Statechart von meiner Seite aus nicht verstand. Ich fand, dass MSM einfacher zu verwenden war, da es Multithreading nicht ansprach.

4
Gordon M. Smith

Als Antwort auf Tims späten Eintritt in die Diskussion (der auch einen der sehr frühen Kommentare von Lev anspricht).

Als einer der Befürworter einer Trennung des Ausgangs von den Destruktoren im Zustandsdiagramm (Argument basierend auf einem realen Anwendungsfall, über die Interaktion mit der realen Welt, dh E/A) seit der Übermittlung an Boost stimme ich zu, dass es Probleme beim Setzen des Ausgangs geben kann Logik in Destruktoren. Kein Wunder, dass David Abrahams auch in Bezug auf die Ausnahmesicherheit überzeugende Argumente vorbrachte. Aus diesen Gründen verlangt Statechart nicht, dass Sie Logik in Destruktoren einfügen - aber es ermöglicht Ihnen dies - mit den üblichen Ratschlägen.

Logik, die immer nur als Teil eines Zustandsübergangs ausgeführt werden soll (nicht als Zerstörung des gesamten Zustandsdiagrammobjekts), kann (und sollte, wenn auch eine Ressourcenbereinigung erforderlich ist) in eine separate exit () - Aktion aufgeteilt werden.

Für einen "schlanken" Zustand ohne aktiven Zustand (Ressourcen), nur auszuführende Eingangs-/Ausgangsaktionen, können Sie diese Aktionen in ctor und d'tor ausführen und sicherstellen, dass der Konstruktor und der Destruktor nicht ausgelöst werden. Es gibt keinen Grund für sie - es gibt keinen Staat, an dem RAII durchgeführt werden kann - es ist nicht schlimm, wenn die Fehlerbehandlung an diesen Orten entsprechende Ereignisse auslöst. Möglicherweise müssen Sie noch überlegen, ob Exit-Aktionen, die den externen Status ändern, bei einer Zerstörung der Statusmaschine ausgeführt werden sollen. Setzen Sie sie dann in die Exit-Aktion, wenn sie in diesem Fall nicht ausgeführt werden sollen.

Statechart modelliert die Aktivierung als Instanziierung eines Objekts. Wenn Ihr Konstruktor also echte Arbeit/Aktivierung/Instanziierung zu erledigen hat und der Status nicht eingegeben werden kann, unterstützt Statechart dies, indem Sie die Möglichkeit haben, eine Ausnahme einer zuzuordnen Veranstaltung. Dies wird so gehandhabt, dass die Statushierarchie nach einem äußeren Status durchsucht wird, der das Ausnahmeereignis behandelt, analog zu der Art und Weise, wie der Stapel für ein Aufrufstapel-basiertes Aufrufmodell abgewickelt worden wäre.

Dies ist alles gut dokumentiert - ich schlage vor, Sie lesen die Dokumente und versuchen es. Ich schlage vor, dass Sie Destruktoren verwenden, um "Softwareressourcen" zu bereinigen und Aktionen zu beenden, um "reale Exit-Aktionen" auszuführen.

Es ist zu beachten, dass die Weitergabe von Ausnahmen in allen ereignisgesteuerten Umgebungen ein Problem darstellt, nicht nur in Zustandsdiagrammen. Es ist am besten, Fehler in Ihr Zustandsdiagramm einzubeziehen, und zwar genau dann, wenn Sie sie nicht auf andere Weise behandeln können, indem Sie auf die Ausnahmezuordnung zurückgreifen. Zumindest funktioniert das bei mir - ymmmv ....

2
da77a