Диаграмма состояний ускорения против машины состояний мета

145

Очевидно, boost содержит две отдельные библиотеки для конечных автоматов: Statechart и Meta State Machine (MSM). Слоганы дают очень похожие описания:

  • Boost.Statechart - Конечные автоматы произвольной сложности могут быть реализованы в легко читаемом и поддерживаемом коде C ++.
  • Meta State Machine - высокопроизводительная библиотека для выразительных конечных автоматов UML2.

Знаете ли вы, в чем заключаются основные различия и что нужно учитывать при выборе между ними?

FireAphis
источник
5
Хехе, еще один очень интересный случай, но никто не знает ответа ... :)
j_random_hacker
10
: D Этот вопрос - вершина моего ТАК опыта! Получение ответов от обоих разработчиков ... может быть лучше ?! Большое спасибо Кристофу и Андреасу.
FireAphis 01
3
Диаграмма состояний позволяет вам добавлять функциональные возможности в конструкторы и деструкторы. Это антипаттерн, особенно с деструкторами.
Лев
2
В диаграмме состояний действия выхода можно поместить в отдельный обработчик exit (), который вызывается перед уничтожением. Я думаю, что это положение смягчает основную проблему антипаттерна, о котором упоминает Лев.
Тим Крюс,
1
В качестве третьего варианта вы также можете рассмотреть эту библиотеку C ++ 11 FSM: github.com/skramm/spaghetti
kebs 06

Ответы:

118

Поскольку, похоже, есть большой интерес, позвольте мне высказать свое (явно предвзятое) мнение, к которому следует относиться с недоверием:

  • МСМ намного быстрее
  • MSM не требует RTTI или чего-либо виртуального
  • MSM имеет более полную поддержку UML2 (например, внутренние переходы, ортогональные области, соответствующие UML)
  • MSM предлагает описательный язык (на самом деле несколько). Например, используя интерфейс eUML, переход можно описать как Источник + Событие [Защита] / Действие == Цель
  • MSM заставит ваш компилятор страдать из-за больших конечных автоматов, поэтому вам понадобится довольно свежий компилятор (g ++> = 4.x, VC> = 9)

Вы можете составить себе лучшее мнение, просмотрев комментарии, опубликованные во время обзора MSM. Эта тема много обсуждалась в списке разработчиков.

Кристоф Генри
источник
2
Большое спасибо. Приятно слышать мнение самого разработчика! Теперь нам нужен только ответ Андреаса Хубера :)
FireAphis
16
Незначительная придирка: в режиме выпуска использование C ++ RTTI (dynamic_cast, typeid) для Boost.Statechart строго необязательно.
113

Как уже упоминал Кристоф, одно из ключевых различий между двумя библиотеками - это производительность во время выполнения. В то время как MSM, вероятно, предлагает лучшее, что вы можете здесь получить, Statechart сознательно меняет память и циклы процессора на лучшую масштабируемость.

С Boost.Statechart вы можете распределить макет (то есть состояния, переходы) вашего конечного автомата по нескольким единицам перевода (файлам cpp) способами, которые вы не можете с MSM. Это позволяет сделать реализацию больших автоматов более удобной в обслуживании и получить гораздо более быструю компиляцию, чем при использовании MSM.

Независимо от того, будут ли накладные расходы на производительность Statechart по сравнению с MSM действительно значительными для вашего приложения, часто довольно легко ответить, если вы спросите себя, сколько событий ваше приложение должно будет обрабатывать в секунду.

Предполагая, что конечный автомат средней сложности реализован с помощью Boost.Statechart, вот несколько приблизительных цифр:

  • Самое современное оборудование ПК легко справляется с> 100 000 событий в секунду
  • Даже оборудование с очень ограниченными ресурсами сможет обрабатывать несколько сотен событий в секунду.

Что касается загрузки ЦП, если количество событий для обработки намного меньше этих чисел, накладные расходы Boost.Statechart по сравнению с MSM почти наверняка не будут заметны. Если число намного выше, вам определенно будет лучше с МСМ.

Более подробную информацию о компромиссах производительности / масштабируемости можно найти здесь: http://www.boost.org/doc/libs/1_45_0/libs/statechart/doc/performance.html


источник
9
Привет, Андреас, насчет распространения макета, были некоторые улучшения. Теперь вы можете компилировать субмашины на разных ядрах. Это не идеально, но заметное улучшение. См. Svn.boost.org/svn/boost/trunk/libs/msm/doc/HTML/…
Кристоф Генри
@ChristopheHenry, ссылка требует логина и пароля. Есть ли шанс публичного доступа? Спасибо.
neonxc
11

При написании моей собственной реализации PPP я использовал диаграмму состояний по трем причинам: 1) диаграмма состояний проще и имеет более понятную документацию; 2) Мне очень не нравится UML :)

Документы по ускорению говорят, что MSM как минимум в 20 раз быстрее, но компилируется довольно медленно для больших FSM.

пылать
источник
7
Хотя я согласен с тем, что большая часть UML - это новая одежда императоров, диаграммы состояний - единственное, что действительно имеет ценность в UML.
Jon Trauntvein
4
Определенно, но я изучил диаграммы состояний с помощью дискретной математики, а не разработки программного обеспечения. Это оставляет след :)
blaze
4

Некоторое время назад я начал с Statechart и перешел на MSM, потому что его было проще использовать в сочетании с asio из одного потока. Мне не удалось связать Statechart и его возможности многопоточности с использованием asio - вероятно, это было своего рода непонимание Statechart новичком с моей стороны. Я обнаружил, что MSM проще использовать, поскольку он не решает проблему многопоточности.

паучья карма
источник
2
Большинство типов диаграмм состояний также не обращаются к потокам. Что касается многопоточности, вы должны иметь возможность использовать boost :: statechart :: state_machine точно так же, как аналог MSM. boost :: statechart :: asynchronous_state_machine и связанные типы являются строго необязательной частью библиотеки диаграмм состояний.
3

В ответ на позднее вступление Тима в обсуждение (которое также относится к одному из самых ранних комментариев Льва).

Как один из тех, кто выступал за разделение выхода из деструкторов в диаграмме состояний (аргумент, основанный на реальном варианте использования, о взаимодействии с реальным миром, то есть ввод-вывод), еще когда он был отправлен в Boost, я согласен, что могут возникнуть проблемы с помещением exit логика в деструкторах. Неудивительно, что Дэвид Абрахамс также привел убедительные аргументы относительно безопасности исключений. По этим причинам Statechart не требует, чтобы вы помещали логику в деструкторы, но позволяет вам это делать обычным советом.

Логика, которая должна запускаться только как часть перехода из состояния (а не разрушения объекта диаграммы состояний в целом), может (и должна, если есть также очистка ресурсов) быть выделена в отдельное действие exit ().

Для «тонкого» состояния без активного состояния (ресурсов), нужно выполнить только действия входа / выхода, вы можете выполнить эти действия в ctor и d'tor и убедиться, что конструктор и деструктор не бросают. Для них нет причин - нет состояния для выполнения RAII - нет ничего плохого в том, что обработка ошибок в этих местах вызывает соответствующие события. Возможно, вам все еще нужно подумать, хотите ли вы, чтобы действия выхода, которые изменяют внешнее состояние, выполнялись при уничтожении конечного автомата ... и помещали их в действие выхода, если вы не хотите, чтобы они происходили в этом случае ...

Диаграмма состояний моделирует активацию как создание экземпляра объекта, поэтому, если у вашего конструктора есть реальная работа / активация / создание экземпляра, и если он может дать сбой, так что состояние не может быть введено, Statechart поддерживает это, давая вам возможность сопоставить исключение с событие. Это обрабатывается способом, который обрабатывает иерархию состояний, ища внешнее состояние, которое обрабатывает событие исключения, аналогично тому, как стек будет раскручиваться для модели вызова на основе стека вызовов.

Все это хорошо задокументировано - я предлагаю вам прочитать документацию и попробовать. Я предлагаю вам использовать деструкторы для очистки «программных ресурсов» и действия выхода для выполнения «реальных действий выхода».

Стоит отметить, что распространение исключений представляет собой небольшую проблему во всех средах, управляемых событиями, а не только в диаграммах состояний. Лучше всего рассуждать о сбоях / ошибках и включать их в структуру диаграммы состояний, и если и только если вы не можете справиться с ними другим способом, прибегайте к сопоставлению исключений. По крайней мере, у меня это работает - ммммм ....

da77a
источник
Спасибо, я вижу, что все мои проблемы в достаточной степени рассмотрены в части «Обработка исключений» учебного пособия Boost :: statechart. В этом случае, я думаю, что (вводящий в заблуждение) комментарий Льва можно решить, просто указав на раздел этого руководства, посвященный «двухэтапному выходу». Я бы подумал об удалении своего ответа, за исключением того, что ваш собственный ответ добавляет ценную информацию в эту тему.
Тим Крюс