Блок TRANSFER позволяет осуществлять безусловные и статистические переходы. Тип перехода определяется в операнде А, направление перехода - в операндах В и С.
В режиме безусловного перехода операнд А в блоке пуст. Все транзакты переходят к блоку, указанному в поле В. Например:
TRANSFER, NEXT
Если блок, к которому направляется транзакт, в текущий момент системного времени не может его принять (например, блок SEIZE), то транзакт остается в блоке TRANSFER и повторяет попытку перехода при каждом пересчете системного времени симулятором.
Если в поле А блока TRANSFER записана десятичная дробь, начинающаяся точкой, то блок работает в режиме статистического перехода. Здесь десятичная дробь определяет вероятность перехода транзакта к блоку, имя которого указывается на поле С. При этом поле В пустое. С вероятностью (1-<А>) транзакт переходит к блоку, следующему за блоком TRANSFER.
Если оба блока заняты, то транзакт остается в блоке TRANSFER и повторяет попытку перехода к выбранному ранее блоку при каждом изменении системного времени.
С помощью этого блока можно промоделировать, например, выбор покупателями в магазине одного из двух отделов, если известно, что половина покупателей направляется в 1-й отдел, а вторая половина - во 2-й отдел:
TRANSFER,5,,OTD2
OTD1 SEIZE PROD1
.
.
.
OTD2 SEIZE PROD2
Условный переход. Для организации условного перехода используется оператор IF, операнд А которого указывает условие перехода транзактов, а в поле В указывается имя блока, куда направляются транзакты, если условие перехода выполняется.
При описании условия используются операции отношения: >, <, =, а также различные СЧА объектов, числовые константы, мнемокоды. Например, при входе транзакта а оператор
IF KASS=NU,KAS1 проверяется условие свободно ли устройство с именем KASS.
Если устройство свободно, то транзакт направляется к блоку с именем KAS1, в противном случае транзакт направляется к блоку, стоящему непосредственно за оператором IF.
Условная задержка транзакта. В случае, если необходимо задержать транзакт перед каким-либо блоком до выполнения определенного условия, используется оператор WAITIF. В поле А этого оператора задается условие задержки, и транзакт остается в данном блоке до тех пор, пока это условие истинно, как только условие становится ложным, транзакт продолжает свой путь.
Здесь для описания условия используется только операция сравнения, где слева указывается имя памяти либо устройства, чье состояние проверяется, а справа - мнемокод состояния. Например, в блоке
WAITIF STR=F
транзакт будет задержан до тех пор, пока память с именем STR будет полной.
Пример 4
В магазине находится два отдела: продовольственный и промтоварный. Около 30-ти процентов приходящих в магазин покупателей направляются в промтоварный отдел, остальные - в продовольственный. Причем, если очередь в промтоварном отделе больше двух человек, а в продовольственном - больше пяти, то покупатели уходят из магазина, не дожидаясь обслуживания. Время прихода и обслуживания покупателей распределено экспоненциально. Среднее значение времени прихода равно соответственно 20 с, времени обслуживания в продовольственном отделе - 30 с и в промтоварном - 35 с.
Модель, имитирующая работу магазина за 8 ч:
SIMULATE
GENERATE 20.FN$XPDIS приход покупателей
TRANSFER 3,,PROM выбор покупателем отдела
* работа продовольственного отдела
PROD IF Q$LIN1>5,BYBY если очередь больше 5-ти чел.-
уход покупателя
QUEUE LIN1 поставить в очередь в продовольствен-
ный отдел
SEIZE PRODI занять продавца
DEPART LIN1 покинуть очередь в продовольствен-
ный отдел
ADVANCE 30,FN$XPDIS обслуживание покупателя
RELEASE PROD1 освободить продавца
TERMINATE уход покупателя
* работа промтоварного отдела
PROM IF Q$LIN1>2,BYBY
QUEUE LIN2
SEIZE PROD2
DEPART LIN2
ADVANCE 35,FN$XPDIS
RELEASE PROD2
BYBY TERMINATE
* таймер
GENERATE 2880
TERMINATE 1
START 1
END
Работа с памятью
Память - особый объект языка, который призван имитировать разного рода накопители, используемые в исследуемых системах, в которых может одновременно находиться несколько транзактов. Для каждой применяемой памяти пользователь должен указать ее емкость - объём памяти, определяющий максимальное количество транзактов, которые могут одновременно находиться в ней. Для указания емкости используется оператор описания памяти STORAGE. Как любой оператор описания языка этот блок помешается между блоком SIMULATE и первым блоком GENERATE. Поле метки содержит имя памяти, а операнд А указывает емкость памяти. Например, для описания памяти емкостью 10 единиц используется блок
SIR STORAGE 10.
В начальный момент времени все памяти пустые. Если в ходе моделирования транзакт обращается к неописанной памяти, ее объем принимается равным 231 -1 единиц.
Блок ENTER - занять память. В поле А блока указываемся имя памяти, в которую помещается транзакт, в поле В - число единиц памяти, занимаемых транзактом при входе. Когда транзакт входит в блок ENTER, определяется число свободных единиц памяти. Если значение операнда В не превышает числа свободных единиц памяти, то число занятых единиц увеличивается на значение операнда В. В этом случае транзакт входит в блок ENTER без задержки. Если же значение операнда В превышает число свободных единиц памяти, то транзакт задерживается перед входом в блок ENTER. Задержанные, при обращении к памяти транзакты, упорядочиваются по приоритету.
Если поле В в блоке ENTER пустое, то число занимаемых единиц памяти принимается равным единице.
Пусть транзакт "х" задержан перед входом в блок ENTER. Если для транзакта "у", приходящего после "х", свободной емкости памяти достаточно, то "у" войдет в блок без задержки.
Блок LEA VE - освободить память. В поле А блока указывается имя освобождаемой памяти, в поле В - число освобождаемых единиц. В случае пустого поля В число освобождаемых единиц памяти принимается равным единице. При входе транзакта в блок LEAVE количество занятых единиц памяти, указанной в поле А, уменьшается на значение операнда В. Перед входом в блок транзакты не задерживаются. Транзакт не должен освобождать большее число единиц памяти, чем их всего занято. Если же транзакт пытается это сделать, то симулятор выдает на печать сообщение об ошибке и прекращает выполнение модели.
В тот момент модельного времени, когда транзакт освобождает память, симулятор
просматривает список задержанных у памяти транзактов, если они есть. Для каждого очередного транзакта проверяется, может ли он теперь быть обслужен памятью. Если такая возможность есть, то симулятор перемещает этот транзакт в блок ENTER, и в результате число занятых единиц памяти соответствующим образом увеличивается.
Транзакт не обязан освобождать такое же число единиц памяти, какое занимал. Он может также освобождать память, которую не занимал. Транзакт имеет право занимать и освобождать любое количество памятей, при этом операции занятия и освобождения могут чередоваться в произвольном порядке.
Пример 5
Автомобили подъезжают к бензозаправочной станции в среднем каждые 4±2 мин. На станции есть две бензоколонки, каждая из которых используется в среднем 5±1 мин. Автостоянка при станции рассчитана на 4 автомобиля. Если подъехавший автомобиль застает обе бензоколонки занятыми, то он встает в очередь на автостоянку. Если же все места и на автостоянке заняты, то автомобиль проезжает мимо. Промоделировать работу станции за 12 часов.
SIMULATE
STO STORAGE 4 места под автостоянку
COL STORAGE 2 бензоколонки
GENERATE 4,2 приезд автомобиля
IF STO=F,BYBY если места заняты - проезжает
ENTER STO занять место на автостоянке
ENTER COL занять бензоколонку
LEAVE STO освободить автостоянку
ADVANCE 5,1 заправиться
LEAVE COL освободить бензоколонку
BYBY TERMINATE покинуть станцию
GENERATE 720 таймер
TERMINATE 1 покинуть станцию
START 1
END