Ptolemy
Ptolemy – это среда моделирования параллельных гетерогенных систем, работающих в режиме реального времени. Проект разрабатывается студентами университета Беркли под руководством профессора Эдварда Ли (Edward Lee). В качестве языка разработки используется Java. Ptolemy постоянно развивается. Добавляется поддержка новых моделей вычислений и новые демонстрационные модели, расширяется документация.
Ptolemy позволяет работать с десятком различных моделей вычислений, среди которых есть, например, дискретно временная модель (discrete-event modeling) и конечный автомат (finite-state machine). В основе моделирования лежат понятия Actor и Director, которые можно перевести как «Исполнительное звено» и «Управляющее звено» соответственно. Director задаёт модель вычисления, в которой работает симулируемая система. Множество Actor'ов в сочетании со связями между ними определяют собственно устройство системы. В рамках первой статьи я хочу обратиться к дискретно-временной модели.
Discrete Event
DE предоставляет основные инструменты для симуляции систем реального времени, например, систем массового обслуживания и сетей связи. Процесс имитационного моделирования представляет собой перемещение маркеров (token) между Actor'ами. Маркер по своей сути представляет какую-либо структуру данных. Когда маркер попадает в Actor, он запустить какое-либо действие, которое может изменить внутренне состояние Actor'а и породить новые события. DE-планировщик гарантирует, что все события происходят строго синхронно. Передача маркера между Actor'ами не занимает времени. Важно помнить, что маркеры не могут самопроизвольно появляться или исчезать.
Соберём простую дискретно-временную модель. Пусть это будет канал передачи данных, в котором моделируется задержка и потеря пакетов. В роли пакетов будут выступать маркеры. Для начала откроем окно редактора (File — New — Graph Editor). Большую часть окна занимает рабочая область, на которой предстоит собирать модель. Слева от рабочей области находится библиотека Actor'ов и Director'ов. Добавим на рабочую область DE Director из раздела Directors. Вместо английского слова Actor, которе в данном контексте лаконично на русский никак не переводится, далее я буду использовать слово «блок».
Поскольку маркеры не могут самопроизвольно появляться и исчезать, нам понадобится какой-нибудь источник. Используем блок SingleEvent из раздела Actors/DomainSpecific/DescreteEvents. Работает этот блок не хитро: выдаёт один маркер в указанный момент времени. Значение маркера и время можно указать в настройках блока (окно настройки параметров открывается двойным щелчком на блоке). Далее нам потребуется смоделировать задержку передачи пакетов в канале. Для этого добавим блок Server из того же раздела библиотеки.
![image](https://habrastorage.org/getpro/geektimes/post_images/688/5e0/7ba/6885e07bafb92439594faa29f181def2.png)
Соединим выход SingleEvent со входом сервера.
![image](https://habrastorage.org/getpro/geektimes/post_images/52d/60d/27e/52d60d27e20f994ed3941d7f5401a7c4.png)
![image](https://habrastorage.org/getpro/geektimes/post_images/afa/72e/ee1/afa72eee1009388eaf816f417736658c.png)
![image](https://habrastorage.org/getpro/geektimes/post_images/8f5/f59/f43/8f5f59f433ab1d96be958731d037aea0.png)
Пока что блок Server задерживает любой маркер на строго определенное время, указанное в его параметрах. Внесём элемент случайности. Для этого понадобится блок Uniform из раздела Actors/Random, который при поступлении маркера на вход генерирует новый маркер со случайным значением, распределенным по нормальному закону между нижней и верхней границами (задаются в параметрах).
![image](https://habrastorage.org/getpro/geektimes/post_images/82f/ce4/a04/82fce4a04878cc2cf01416f5d4a41917.png)
![image](https://habrastorage.org/getpro/geektimes/post_images/305/4bd/9bb/3054bd9bb0831f5803dae6bcd3ff0a18.png)
Для грубого соответствия смоделированного канала реальному не хватает только потерь пакетов при их передаче. Для моделирования потерь используем блок DiscreteRandomSource из того же раздела Random. В его параметре values указывается массив генерируемых значений, а в параметре pmf (Probability mass function) — массив вероятностей генерации каждого значения. Укажем в values значения 0 и 1, а в pmf — 0.85 и 0.15.
![image](https://habrastorage.org/getpro/geektimes/post_images/05a/b6e/7fe/05ab6e7fedb193ecba7241184a3a7dfa.png)
При приходе маркера на вход trigger блок с вероятность 85% будет генерировать ноль и с вероятность 15% — единицу. Соединим вход trigger с выходом сервера. (Для ветвления линий используются узлы — черный ромб на панели инструментов) Используем эти значения в качестве признака потери (единица — пакет потерян).
![image](https://habrastorage.org/getpro/geektimes/post_images/49c/69c/654/49c69c6547c13ef0402fdc7c6a8c7cb7.png)
Такой простой канал сам по себе представляет небольшой интерес, зато его удобно использовать для моделирования сетевых протоколов. Смоделированный канал может передавать пакеты со случайной задержкой и терять их с определенной вероятностью.
Ptolemy позволяет создавать новые Actor'ы, собирая их из уже существующих. В разделе библиотеки Utilities находится блок CompositeActor, в который можно поместить любые другие блоки, в том числе и CompositeActor. Поместим модель канала в CompositeActor. Рабочая область CompositeActor открывается командой OpenActor из контекстного меню. Блок SingleEvent больше не нужен. Вместо этого добавим один входной и один выходной порт.
![image](https://habrastorage.org/getpro/geektimes/post_images/e07/314/5c5/e073145c546b17a8fc2adf66f2858c0f.png)
Можно упростить работу с каналом, если «вывести наружу» все важные параметры: нижнюю и верхнюю границы диапазона временных задержек и вероятность потери пакета. Для этого в окне настройки параметров блока добавим параметры lowDelayBorder, highDelayBorder и lossProbability. Кнопка Add вызывает соответствующий диалог, в котором в частности можно указать значения по-умолчанию для добавляемых параметров. Имена новых параметров теперь доступны внутри блока. Заменим конкретные значения именами параметров в блоках Uniform и DiscreteRandomsource.
![image](https://habrastorage.org/getpro/geektimes/post_images/50d/730/65f/50d73065fb531109ec3884452b4c9012.png)
Собрав примитивный источник пакетов:
![image](https://habrastorage.org/getpro/geektimes/post_images/70b/52c/0f5/70b52c0f5edf25d08e75488b6d603a33.png)
можно протестировать работу канала:
![image](https://habrastorage.org/getpro/geektimes/post_images/983/25e/af3/98325eaf3a661137042a1ffa5757d52f.png)
В настройках DE Director'а есть важный параметр — stopTime. По-умолчанию он выставлен в бесконечность, но для наблюдения за такой простой моделью будет вполне достаточно значения 50.
На этом разрешите закончить знакомство с Птолемеем. Если тема окажется востребованной, то вскоре последует продолжение.