Для представления собственно обслуживания используются определенные элементы. Такими элементами могут быть либо люди, либо какие-то предметы. Независимо от этого подобные элементы в GPSS называют объектами аппаратной категории, к которой относят одноканальные (ОКУ) и многоканальные устройства (МКУ) и логические ключи.
Рассмотрение методов построения моделей с устройствами начнем с имитации функционирования ОКУ.
При моделировании возможны следующие режимы организации функционирования ОКУ:
вспомним, что потоки, существующие в реальных системах, в моделях имитируют транзакты. Поэтому сначала узнаем, как вводятся транзакты в модель и как выводятся из нее. А так как построение самых простейших моделей невозможно без некоторых блоков GPSS, такие блоки будут также рассмотрены.
GENERATE - это блок, через который транзакты входят в модель. Блок GENERATE имеет следующий формат записи:
GENERATE [A],[B],[C],[D],[E]
Скобки [ ] означают, что данный операнд является необязательным. Не существует ограничений на число различных блоков GENERATE в одной модели.
Интервалы времени между последовательными появлениями транзактов блока GENERATE называют интервалом поступления. Все разработчики должны задавать спецификацию распределения интервалов времени поступления в блоке GENERATE. Информация, необходимая для этого, задается операндами А и B. Все возможные виды распределения интервалов времени поступления в GPSS делят на равномерно распределенные и все другие виды распределения.
Операнд А - средний интервал времени между последовательными поступлениями транзактов в модель.
Операнд B - задает модификатор, который изменяет значения интервала генерации транзактов по сравнению с интервалом, указанным операндом А. Есть два типа модификаторов: модификатор-интервал и модификатор-функция.
С помощью модификатора-интервала задается равномерный закон распределения времени между генерацией транзактов.
Операнды А и B могут быть именем, положительным числом, выражением в скобках или непосредственно СЧА.
При вычислении разности значений (А-В), заданных операндами А и B, получается нижняя граница интервала, а при вычислении суммы (А+В) - верхняя граница. После генерации очередного транзакта выбирается число из полученного интервала, это и будет значение времени, через которое следующий транзакт выйдет из блока GENERATE.
Когда операнды А и B задают в виде констант ( B - модификатор-интервал), они должны быть неотрицательными числами, т. е. интервал времени может быть выражен числами, например, 4.1,…,12.7. Предположим, что транзакт входит в модель - блок GENERATE - в момент модельного времени 25.6. После того, как этот транзакт попадет в следующий блок модели, планировщик GPSS разыграет случайное значение из распределения интервалов времени, равного .
Пусть разыгранным значением будет число 9.7. Тогда планировщик планирует приход следующего транзакта в блок GENERATE в момент времени 25.6+9.7=35.3.
Можно выбрать для розыгрыша генератор равномерно распределенных случайных чисел. Это устанавливается на странице " Random Numbers " ( Случайные числа ) в журнале настроек модели. Нужно выбрать Edit/Settings ( Правка/Настройка ) и страницу " Random Numbers " ( Случайные числа ), на которой в поле ввода " GENERATE " ввести номер генератора - любое положительное целое число. По умолчанию используется генератор равномерно распределенных случайных чисел номер 1.
Операнды А и В не обязательно должны быть заданы. Когда один или оба операнда не указаны, по умолчанию предполагается их нулевое значение. Например, А=16.4, В=0. Поскольку операнд В=0, то интервалы времени распределены равномерно, , т. е. интервал времени поступления равен 16.4. Это пример того, как может быть задано детерминированное значение интервалов времени.
Более сложные интервалы времени поступления транзактов (не по равномерному закону) могут быть заданы с использованием модификатора-функции или встроенных генераторов случайных чисел. Под действием модификатора-функции значение операнда А умножается на значение функции, заданной операндом В.
При любом способе вычисления интервала времени значение операнда В не должно превышать значения операнда А, в противном случае в блоке GENERATE может быть получен отрицательный интервал времени, который вызовет останов по ошибке "Отрицательное время задержки".
Рассмотрим три дополнительных операнда: С - смещение интервалов, D - ограничитель, Е - уровень приоритета.
Смещение интервалов (первоначальная задержка) С - это момент времени, в который в блоке GENERATE должен появиться первый транзакт. После этого первого прихода все остальные приходы транзактов возникают в соответствии с распределением интервалов времени, задаваемых операндами А и B. Операнд С можно использовать как для ускорения, так и для замедления прихода первого транзакта или для указания прихода в нужный момент времени. Начальная задержка может быть меньше, равна или больше среднего времени, заданного операндом А. Когда операнд С не используется, интервалы генерирования определяются операндами А и B (они не оказывают влияния на задержку). Операнд С может быть таким же как и операнды А и B.
Операнд D задает граничное значение общего числа транзак-тов, которые могут войти в модель через данный блок GENERATE в течение времени моделирования. Когда это число достигнуто, данный блок GENERATE перестает быть активным. Если не определено граничное значение (операнд D не используется), блок GENERATE остается активным в течение всего времени моделирования, т. е. по умолчанию ограничения на количество создаваемых транзактов нет.
Операнд Е устанавливает класс приоритета каждого из транзак-тов, входящих в модель через данный блок GENERATE. Для задания приоритетов c целью повышения эффективности работы GPSS World рекомендуется использовать последовательность целых чисел 0, 1, 2, 3,… вместо, например, 37, 43, 88, 122,... Чем выше число, тем выше приоритет. Если операнд Е не используется, по умолчанию приоритет генерируемых данным блоком GENERATE транзактов равен нулю.
Операнды D и Е могут задаваться также как и операнды А, B и С, но при этом принимать значения только целых положительных и целых чисел соответственно.
В любом блоке GENERATE должен быть обязательно задан либо операнд А, либо операнд D. Нельзя использовать в качествеоперанда параметры транзактов. Необходимо также помнить, что транзакт не должен входить в блок GENERATE. Если транзакт пытается это делать, возникает ошибка выполнения. Приведем примеры записи блоков GENERATE:
GENERATE 38.6 GENERATE X$IntPostTran GENERATE MX$VrPost(3,6) GENERATE V$Prom GENERATE (Exponential(11,0,X$Mat)) GENERATE IntPostTran
GENERATE 73.25,X$Otk GENERATE X$Sredne,FN2 GENERATE Sredne,FN4 GENERATE (V$Post+7.1),FN$Mod
GENERATE 7.3,,4.1 GENERATE 7.3,,X$VrSm GENERATE V$IntP,,MX2(X$Stroka,X$Stolbez) GENERATE (Normal(3,X$Sre,X$SreOtk)),,Sme
GENERATE 13.3,2.8,,,1 GENERATE (Normal(8,X$Sr,X$SrOtk)),Post,,1 GENERATE V$IntPostTran,(V1-12.3),,12
Приведенные примеры демонстрируют различные способы задания операндов блока GENERATE. Однако при этом нужно помнить следующее.
В начальный момент времени в каждом блоке GENERATE производится подготовка к выходу одного транзакта. На этой стадии модель еще полностью не инициализирована для выполнения, т. е. не все переменные получили значения. Но описанные в блоке GENERATE, должны быть уже определены - инициализированы. Поэтому в модели блоку GENERATE должны предшествовать команды определения EQU, INITIAL, FUNCTION, VARIABLE, FVARIABLE. Это делается для того, чтобы СЧА в блоке GENERATE, который ссылается на них, давали нужные для ввода транзактов в модель результаты.
Например:
SrIntPost EQU 47.2 StanOtkl EQU 28.6 INITIAL X$KolTrans,43 . . . GENERATE SrIntPost,StOtk,,X$KolTrans
Как видно из примера, блоку GENERATE предшествуют присвоения командой EQU именам числовых значений и командой INITIAL начального значения сохраняемой ячейке с именем Kol-Trans.
Транзакты удаляются из модели, попадая в блок TERMINATE (завершить).
Блоки TERMINATE всегда позволяют войти всем транзактам, которые пытаются это сделать. В модели может быть любое число блоков TERMINATE. Блок имеет следующий формат записи:
TERMINATE [A]
Значением операнда А является число единиц, на которое блок TERMINATE уменьшает содержимое счетчика завершения, определяющего момент окончания моделирования. Операнд А может быть именем, положительным целым числом, выражением в скобках, СЧА или СЧА*<параметр>. По умолчанию значение операнда А равно нулю. В этом случае транзакт уничтожается, а значение счетчика завершения не меняется.
Счетчик завершения представляет собой ячейку памяти с именем TG1, которая хранит положительное целое число. Это число записывается в ячейку TG1 командой START в начале процесса моделирования.
В процессе моделирования транзакты попадают в блок TERMINATE и в соответствии со значением операнда А вычитают определенное число из счетчика завершения. При достижении содержимым счетчика нуля моделирование завершается. В модели может быть много блоков TERMINATE, но счетчик завершения только один.
Когда пользователь подготавливает модель, он задает время моделирования, указывая в операторе START значение счетчика завершения. Поскольку пути прохождения транзактов в модели имеют различный физический смысл, каждый блок TERMINATE может либо уменьшать, либо не уменьшать содержимое счетчика завершения.
Рассмотрим пример, в котором блок TERMINATE и команда START используются для управления временем моделирования. Предположим, что разработчик выбрал в качестве единицы времени 1 мин. Он хочет промоделировать поведение системы в течение 10 часов, затем моделирование должно быть закончено. За единицу модельного времени возьмем 1 мин, тогда время моделирования равно 10*60=600 единицам.
Любая модель на GPSS состоит из одного или нескольких сегментов. Для управления временем моделирования разработчик (см. блок-диаграмму):
В процессе моделирования транзакты, которые двигаются в других сегментах модели, время от времени выводятся из модели в других блоках TERMINATE, но они не оказывают воздействия на счетчик завершения. В момент модельного времени 600 транзакт в приведенном выше сегменте попадает в блок GENERATE и сразу же переходит в следующий блок TERMINATE.
Поскольку операнд А блока содержит 1, то из счетчика завершения вычитается 1. Предположим, что в команде START было указано число 10, т. е. десять прогонов модели, и в счетчик завершений записано число 10: TG1 = 10. После первого вычитания содержимое ячейки TG1 = 9, т. е. не равно нулю. Поэтому моделирование продолжается. После десяти прогонов, т. е. вычитания десяти единиц, TG1 = 0. Планировщик прекращает моделирование.
Команда START используется для запуска процесса моделирования. Она имеет следующий формат записи:
START A,[B],C,[D]
Операнд А задает значение счетчика завершения, определяющего момент окончания прогона модели. Может быть только целым положительным числом. Операнд B - операнд вывода статистики. Он может быть NP ("нет вывода данных") либо опущен. При задании NP стандартный отчет не выводится. По умолчанию выводится стандартный отчет. Операнд С не используется и сохранен для совместимости с описаниями ранних версий GPSS. Операнд D определяет необходимость вывода содержимого списков событий. Если операнд D указать любым положительным целым числом, например, 1, то списки текущих и будущих событий включаются в стандартный отчет и выводятся. Если операнд D опущен, то по умолчанию списки в стандартном отчете не выводятся.
Команду START можно сразу указывать в конце программы модели при ее подготовке и в таком виде записывать на магнитный носитель. Тогда после трансляции модели, т. е. создания объекта "процесс моделирования", сразу начинается моделирование. Этот же оператор можно вводить в программу модели в интерактивном режиме.
Однако может возникнуть необходимость завершить моделирование не по истечении какого-то времени, а после обработки определенного количества транзактов, имитирующих, например, изготовленные детали, переданные по каналу связи сообщения и т. д. В этом случае сегмент задания времени моделирования не нужен. Для организации такого способа завершения моделирования необходимо сделать следующее. В блоках TERMINATE, которые выводят из модели транзакты, имеющие смысл тех же изготовленных деталей или переданных сообщений, указать число, на которое уменьшается счетчик завершения моделирования. В команде START также указать число, деление которого на указанное в блоке TERMINATE число даст требуемое количество изготовленных деталей или переданных сообщений. Например, требуется завершить моделирование после изготовления 100 деталей. В модели это может быть так:
. . . TERMINATE 1 . . . TERMINATE 1 . . . TERMINATE START 100
Блоков TERMINATE, которые выводят из модели транзакты, соответствующие изготовленным деталям, может быть несколько. Все эти блоки должны иметь 1 в качестве операнда А. У остальных блоков TERMINATE, если они есть в модели, операнд А должен быть опущен.
Итак, транзакты введены в модель. Но аналоги транзактов - элементы потоков в реальных системах имеют различные характеристики. Рассмотрим, как эти же характеристики присваиваются транзактам.
Каждый транзакт может иметь любое число параметров. Интерпретация смысла параметров произвольная. В момент генерации транзактов все его параметры нулевые (только те, которые используются в модели). Блок ASSIGN является основным средством для задания значений параметров транзактов.
Формат записи:
ASSIGN A,B,[C]
Операндом А задается номер параметра, которому присваивается значение. Операнд А может быть именем, положительным целым числом, выражением в скобках, СЧА, СЧА*параметр и следующими за ними знаками + (если нужно увеличить), - (если нужно уменьшить).
Операнд B определяет значение, которое следует добавить, вычесть или которым следует заменить значение в параметре, заданном операндом А. Если такой параметр не существует, то он создается со значением, равным 0. Операнд B может быть таким же как и операнд А, кроме того, числом и строкой.
Операнд С задает номер модификатора-функции. При использовании операнда С значение операнда B умножается на значение модификатора-функции. Полученное произведение становится значением, которое изменяет значение параметра, заданного операндом А. Следует отметить, что операнд С определяет номер функции или ее имя (не нужно использовать СЧА FN или FN$ перед ним). Если используется СЧА FN, например, FN3, вычисляется функция номер 3 GPSS. Полученный результат используется для определения второй функции GPSS, которая также вычисляется и ее значение умножается на значение операнда B. Приведем примеры записи блока ASSIGN:
ASSIGN1,754.3 ASSIGN4+,Q5 ASSIGN3-,5.85,7 ASSIGNName,"Plan" ASSIGNTr1-,(Normal(32,Sred,SrOtkl),Expdis
В первом примере параметру 1 присваивается 754.3. Во втором примере к значению параметра 4 прибавляется значение длины текущей очереди номер 5. В третьем примере из значения параметра 3 вычитается произведение 5.85 на вычисленное значение функции номер 7. В четвертом примере параметру с именем Name присваивается строка Plan. В пятом примере вычисляются выражение в скобках и функция с именем Expdis, перемножаются и полученное произведение вычитается из значения параметра с именем Tr1.
В GPSS элементами, которые требуют обслуживания, являются транзакты. Они перемещаются в модели от блока к блоку. Если в какой-то момент активности транзакт занимает ОКУ, то для этого он входит (или пытается войти) в соответствующий блок, описывающий это ОКУ. Блок должен обладать следующими свойствами:
Блок, обладающий этими свойствами, является блоком SEIZE (занято). Вход транзакта в блок SEIZE моделирует занятие ОКУ.
После обслуживания (блок, имитирующий обслуживание, будет рассмотрен в п. 6.2.3) вход того же транзакта в другой блок моделирует освобождение ОКУ. Назначением этого блока является изменение состояния ранее занятого ОКУ с "занято" в "незанято". Этим блоком является блок RELEASE (освободить).
Форматы блоков:
SEIZE A RELEASE A
В обоих блоках операнд А - это имя занимаемого (освобождаемого) ОКУ. Может быть именем, положительным целым числом, выражением в скобках, СЧА, СЧА*параметр. Планировщик автоматически обеспечивает возникновение транзактов и ОКУ, когда этого требует логика модели. В то время как транзакты находятся в модели временно, ОКУ, используемые в модели, существуют постоянно в течение всего процесса моделирования. Прежде чем освободить ОКУ, транзакт может пройти через неограниченное число блоков. Например:
SEIZE Can . . . RELEASE Can
Если ОКУ с именем Can не занято, активный транзакт занимает его. Если ОКУ занято, транзакт помещается в список задержки данного ОКУ позади транзактов с таким же приоритетом. Этот транзакт не входит в блок SEIZE. Транзакту также отказывается во входе в блок SEIZE, если ОКУ с именем CAN находится в недоступном состоянии (режим недоступности ОКУ рассматривается в п. 4.2).
ОКУ, как уже отмечалось, может иметь имя или номер. В данном случае разрешается записывать вместо операнда А номер непосредственно без предварительного присвоения его имени командой EQU. Например:
SEIZE 5 . . . RELEASE 5
Блоки SEIZE и RELEASE при необходимости создания других версий модели могут переопределяться. Для этого они должны иметь метки (не путайте с операндами А этих блоков).
Обычно транзакт занимает ОКУ для того, чтобы немедленно начать на нем обслуживание, которое длится некоторый промежуток модельного времени. В течение этого времени транзакт должен прекратить двигаться по модели. Только по истечении времени обслуживания он должен попасть в блок RELEASE для освобождения ОКУ.
Для задержки транзакта в течение некоторого интервала модельного времени используется блок ADVANCE. Чаще всего этот интервал задается случайной переменной. Как и при использовании блока GENERATE информация, необходимая для описания соответствующего времени обслуживания и его распределения, задается операндами А и B. Формат записи блока ADVANCE следующий:
ADVANCE A,[B]
Здесь А - среднее время обслуживания, а B - способ модификации операнда А. Каждый из операндов А и B может быть именем, числом, выражением в скобках, СЧА или СЧА*параметр.
Как и в блоке GENERATE, модификаторы могут быть двух типов: модификатор-интервал и модификатор-функция, т. е. блок ADVANCE вычисляет время задержки (приращения модельного времени) такими же способами.
Если задан только операнд А, он вычисляется и используется в качестве времени задержки. Например:
ADVANCE (Normal(12,X$Sredn,X$SreOtk))
Время задержки распределено по нормальному закону со средним значением и среднеквадратическим отклонением, предварительно записанными командой INITIAL в сохраняемые ячейки с именами Sredn и SreOtk соответственно. Для генератора нормального распределения источником случайных чисел, равномерно распределенных в интервале [0, 1], является генератор номер 12.
При задании операндов А и B, и B не определяет функцию, оба операнда вычисляются (если они не константы) и в качестве времени задержки выбирается случайное число, равномерно распределенное в интервале (А-В, А+В). Для розыгрыша может быть выбран любой генератор равномерно распределенных случайных чисел. Делается это так же, как и при выборе генератора для блока GENERATE. Только номер генератора на странице "Random Numbers" (Случайные числа) в журнале настроек модели нужно указать в поле ввода ADVANCE. По умолчанию используется генератор случайных чисел номер 1. Например
ADVANCE 56.7,23.2
В данном примере входящий транзакт задерживается на время, равномерно распределенное в интервале от 33.5 до 79.9.
Так же, как и в блоке GENERATE, при любых способах вычисления времени задержки значение операнда B не должно превышать значение операнда А. Если в приведенном выше примере операнд B взять равным 56.8, в процессе моделирования произойдет останов по ошибке "Отрицательное приращение времени".
Для задания времени задержки по другому закону, отличному от равномерного, в операнде B записывается модификатор-функция. При обращении к функции определяется некоторое число - значение функции. Оно умножается на значение операнда А. Результат используется как время задержки. Например:
ADVANCE Ring,FN$Exper
В примере вычисляется значение функции с именем Exper и умножается на значение переменной пользователя Ring, которой предварительно должно быть присвоено числовое значение командой EQU.
Как отмечалось ранее, в блоке GENERATE можно использовать функции и арифметические переменные, предварительно определенные командами FUNCTION и VARIABLE или FVARIABLE. Но в этих командах не должны были быть ссылки на параметры транзактов, так как транзактов еще нет. В операндах блока ADVANCE ссылки на параметры транзактов возможны. Естественно, что этим параметрам пользователем должны быть предварительно присвоены соответствующие значения. Например:
ADVANCE P1 ADVANCE (Exponental(7,0,MX$Sred(P2,P$Stolb))) ADVANCE SrIntPost,FN*2
В первом примере транзакт задерживается на время, равное значению параметра 1. Во втором примере время задержки определяется по экспоненциальному закону. При этом среднее значение выбирается из элемента матрицы, номера строки и столбца которого содержатся в параметре 2 и параметре с именем Stolb соответственно. Для генератора экспоненциального распределения источником равномерно распределенных случайных чисел в интервале [0, 1] является генератор номер 7 (RN7).
В третьем примере время задержки находится как произведение значения переменной пользователя SrIntPost и вычисленного значения функции, номер которой содержится в параметре 2 активного транзакта.
Блок ADVANCE никогда не препятствует входу транзакта. Любое число транзактов может находиться в этом блоке одновременно.
Приведем пример использования блоков SEIZE, ADVANCE и RELEASE (см. блок-диаграмму).
Транзакт, войдя в блок SEIZE, займет ОКУ с символическим именем Rем1, задержится там благодаря блоку ADVANCE на 21+7 единиц времени и затем покинет его. После того, как транзакт войдет в блок RELEASE, планировщик попытается продвинуть транзакт в следующий блок модели, и следующий транзакт попытается использовать ОКУ, называемое Rем1.
Блок ADVANCE можно располагать в любых местах модели, а не только между блоками SEIZE и RELEASE.
Время задержки может быть также равным нулю. Если время равно нулю, транзакт в блоке ADVANCE не задерживается и переходит в следующий блок.
Представим себе, что в какой-либо системе, модель которой вы собираетесь разработать, имеются, например, два канала передачи данных - два ОКУ. Естественно, что если один канал занят, то выясняется: свободен ли второй канал? Если он не занят, надо попытаться передать по этому каналу. Но как проверить состояние каналов в модели?
В GPSS World блок GATE используется для определения состояния устройств без изменения их состояния.
Формат записи:
GATE X A,[B]
Блок GATE работает в двух режимах:
При работе в режиме отказа блок GATE не пропускает транзакты, если соответствующий объект не находится в требуемом состоянии. Если же поставленное в блоке GATE условие удовлетворяется, то активный транзакт входит в него и затем переходит к следующему по порядку блоку. Операнд А определяет имя или номер ОКУ.
Условие задается одним из следующих условных операторов X, связанных с ОКУ:
NU - ОКУ, заданное операндом А, свободно;
U - ОКУ, заданное операндом А, занято.
Как видно, тип проверяемого объекта неявно задается условным оператором (позже мы рассмотрим применение блока GATE для проверки и других объектов аппаратной категории).
Операнд B содержит номер следующего блока для входящего транзакта, когда условный оператор имеет значение "ложь". Операнды А и B могут быть именем, положительным целым числом, выражением в скобках, СЧА, СЧА*параметр. Если операнд B не используется, то проверка проводится в режиме отказа. Если результат этой проверки не будет "истина", то транзакт помещается в список повторных попыток проверяемого объекта. Когда состояние любого из объектов меняется, заблокированный транзакт снова активизируется, повторяется проверка заданного блоком GATE условия. Если это условие выполняется, транзакту разрешается войти в блок GATE и далее перейти к следующему по порядку блоку. Например:
GATE U Zrk GATE NU(FN$Expert+4) GATE NUBat,Oper
В первом примере блок GATE не пропустит транзакт при условии незанятости ОКУ с именем Zrk. Во втором случае - когда занято ОКУ, номер которого определяется как результат вычисления и последующего округления выражения в скобках FN$Expert+4. В третьем примере в случае занятости ОКУ с именем Вat транзакт будет направлен к блоку с именем Oper.
Следует отметить, что несмотря на удобство применения блока GATE, в некоторых случаях это может привести при отсутствии операнда B к увеличению машинного времени за счет проведения проверок для заблокированных транзактов. Уменьшение числа проверок и исключение из проверяемых тех транзактов, для которых вряд ли когда-нибудь результат проверки будет истинным, может быть организовано с помощью блоков LINK и UNLINK. Методы применения этих блоков будут рассмотрены позже.
Для проверки состояния различных объектов, в том числе и ОКУ, можно использовать также булевы переменные и блок TEST.
В GPSS объекты типа "очередь" вводятся для сбора статистических данных. Эта статистика должна дать ответы на вопросы:
GPSS обеспечивает возможность сбора такой статистики с помощью средства, называемого регистратором очереди. При использовании регистратора очереди в тех точках модели, где ресурсы ограничены, планировщик начинает автоматически собирать статистику, описывающую ожидание (если оно есть), возникающее в этих точках. Регистраторы очередей различают заданием имен. Условия задания имен те же, что и у устройств. Разработчик вносит регистратор очереди в модель с помощью пары взаимодополняющих блоков QUEUE (стать в очередь) и DEPART (покинуть очередь).
Формат записи блока QUEUE следующий:
QUEUEA,[B]
Блок QUEUE увеличивает длину очереди. Операнд А задает номер или имя очереди, к длине которой добавляются единицы.
Операнд B определяет число единиц, на которое увеличивается текущая длина очереди. Если операнд B не используется, то прибавляется единица.
Рассмотрим примеры записи блока QUEUE.
QUEUERemQ
Увеличивает длину очереди RemQ на единицу при входе каждого транзакта.
QUEUEР14,Р1
Увеличивает длину очереди, номер или имя которой задан в параметре Р14 транзакта, на число единиц, заданных в параметре Р1.
Формат записи блока DEPART имеет вид:
DEPART A,[B]
Блок DEPART служит для уменьшения длины очереди. Операнд А задает номер или имя очереди, длину которой надо уменьшить. Операнд B задает число единиц, на которое уменьшается длина очереди. Это число не должно превышать текущую длину очереди. Если операнд B не используется, то по умолчанию длина очереди уменьшается на 1. Операнды А и B в блоках QUEUE и DEPART могут быть именем, положительным целым числом, выражением в скобках, СЧА или СЧА*параметр.
Приведем примеры записи блока DEPART.
DEPART RemQ
Уменьшает длину очереди RemQ на единицу. DEPART V3,(V4+3.7)
Операнды А и B заданы арифметической переменной V3 и выражением в скобках, которое также содержит арифметическую переменную V4. При входе транзакта в блок DEPART переменная и выражение в скобках вычисляются и округляются. После этого длина очереди, номер которой есть значение переменной V3, уменьшается на значение выражения в скобках (V4+3.7).
Очереди, как и ОКУ, разрешается записывать вместо операнда А номер без предварительного присвоения его имени командой EQU. Например:
QUEUE5 : DEPART 5
Рассмотрим использование блоков QUEUE и DEPART в модели на примере представленной блок-диаграммы. Ожидание может возникнуть ввиду занятости ОКУ с именем Rem1. Для сбора статистики об ожидании введем регистратор очереди и дадим ему имя RemQ.
Если транзакт вошел в сегмент в момент, когда ОКУ Rem1 не занято, транзакт входит в блок QUEUE. Далее транзакт пытается войти в блок SEIZE и, поскольку Rem1 свободно, эта попытка оказывается успешной. Состояние Rem1 меняется на "занято", и далее транзакт сразу попадает в блок DEPART. Выполняется соответствующая подпрограмма и транзакт попадает в блок ADVANCE, где задерживается на некоторое время, вычисленное в соответствии с распределением .
Предположим теперь, что ОКУ Rem1 находится в занятом состоянии и следующий транзакт входит в сегмент модели. Он проходит в блок QUEUE и получает далее отказ, поскольку Rem1 находится в занятом состоянии. Транзакт перестает двигаться, оставаясь в блоке QUEUE.
Позднее, когда транзакт, находящийся на обслуживании в устройстве, покидает его, ожидающий транзакт опять попытается войти в блок SEIZE. На этот раз попытка окажется успешной. Двигаясь дальше, транзакт войдет в блок DEPART, уменьшая значение счетчика содержимого очереди на 1 (по умолчанию, так как операнд B не используется).
Длина очереди не может быть отрицательной. Если такое произойдет, происходит останов по ошибке "Запрещенная попытка сделать содержимое очереди отрицательным".
Останов по ошибке "Недопустимое отрицательное число в операторе GPSS. Operand B." происходит и тогда, когда при создании очереди делается попытка уменьшить ее длину.
Например:
QUEUEServer,3
Для получения плотности распределения, ее интегральных относительных частот, среднего значения и стандартного отклонения некоторых аргументов, которыми могут быть СЧА (например, времени нахождения транзакта в модели или задержки в ее отдельных частях, длин очередей, содержимого МКУ, коэффициентов использования устройств и т. д.), используются статистические таблицы TABLE и QTABLE.
Команда описания таблицы TABLE имеет следующий формат:
Name TABLE A,B,C,D
Команда определяет аргумент, а также число и ширину частотных интервалов (классов). Метка Name определяет имя таблицы.
Операндом А задается аргумент таблицы - элемент данных, чье частотное распределение будет табулироваться. Операнд может быть именем, выражением в скобках или СЧА.
Операндом B задается верхний предел первого частотного интервала.
Операнд С задает ширину частотного интервала - разницу между верхней и нижней границей каждого частотного класса.
Операнды B и С могут быть числами или strinq.
Операндом D задается число частотных интервалов (положительное целое число).
Для сбора данных транзакт должен войти в блок TABULATE с тем же именем таблицы, которое определено в блоке TABLE. Блок помещается в ту точку модели, которая соответствует исследуемому объекту.
Блок TABULATE имеет следующий формат:
TABULATE A,[B]
Операндом А задается имя таблицы, в которую табулируется значение аргумента.
Операндом B ( весовой коэффициент ) задается число единиц, которые должны быть занесены в тот частотный интервал, в который попало значение аргумента. Если операнд B отсутствует, то по умолчанию эта величина равна 1.
Операнды А и B могут быть именем, выражением в скобках, СЧА или СЧА*параметр. Кроме того, операнд А может быть только положительным целым числом, а операнд B - положительным числом. Например,
VrRem TABLE P$ReaLvs,8.2,5.5,10 . . . TABULATE VrRem
Оператором TABLE описывается таблица с именем VrRem. Аргументом таблицы является СЧА P$ReaLvs с верхним пределом первого интервала 8.2, шириной 5.5 и числом интервалов 10. Каждое значение табулируемого аргумента P$ReaLvs, меньшее или равное 8.2, увеличивает частоту первого частотного класса таблицы на 1. Если аргумент таблицы не попадает в первый частотный класс, класс определяется делением значения аргумента на операнд С оператора TABLE. Например, значение P$ReaLvs равно 30.25. Тогда 30.25/5.5=5.5 и будет увеличена на 1 частота шестого класса. Если аргумент A таблицы больше B+C#D=8.2+5.5#10= =63.2, изменен будет на 1 последний (десятый) класс. Одновременно корректируются текущие значения СЧА таблицы: счетчик входов в таблицу ТС, среднее время ожидания ТВ и стандартное отклонение времени ожидания TD. Собранная в таблице статистика выводится в стандартный отчет.
При использовании в операнде B блока TABULATE весового коэффициента, например:
TABULATE VrRem,3
последний будет добавляться к значению частоты частотного класса. Весовой коэффициент применяется также для среднего и стандартного отклонения, что равносильно нескольким входам в блок TABULATE.
Таким образом, команда TABLE вместе с блоком TABULATE служат для табулирования любого СЧА.
Кроме таблиц TABLE могут использоваться Q -таблицы, являющиеся средством получения распределения только времени пребывания транзакта в очереди. Формат команды описания Q -таблицы такой же, как и TABLE. Отличие состоит в том, что операндом А задается имя очереди. Назначение операндов B, С, D такое же, что и в команде описания TABLE. Операнд B может быть нулем или положительным числом. Для создания в модели такой таблицы ее нужно предварительно определить с помощью команды QTABLE формата:
Name QTABLE A,B,C,D
Например:
VTime QTABLE Dlina,18.2,4.3,6
Dlina - имя очереди к устройству, а не СЧА, как в случае использования TABLE.
При прохождении транзакта через блоки QUEUE и DEPART его время ожидания фиксируется, и к счетчику частотного интервала таблицы, в который попало это время, добавляется 1. Одновременно в таблице накапливается информация для вычисления среднего значения и среднеквадратического отклонения времени ожидания. Следует обратить внимание, что при использовании QTABLE информация в таблицу заносится автоматически при входе транзакта в блоки QUEUE и DEPART и никаких специальных мер, т. е. блока TABULATE, при этом не требуется.По окончании моделирования собранная в таблице информация также выводится в стандартном отчете GPSS.
Для изменения маршрутов движения транзактов в модели применяются блоки DISPLACE, LOOP, GATE, TEST и TRANSFER. Здесь мы рассмотрим методы применения блоков TRANSFER и DISPLACE.
Блок TRANSFER (передать) предназначен для передачи входящего в него транзакта в любой другой блок модели. Он имеет следующий формат:
TRANSFER [A],[B],[C],[D]
Все режимы блока TRANSFER, кроме безусловного, выборочные, т. е. отличаются друг от друга способом выбора очередного блока, к которому должен быть направлен активный транзакт. Операнд А задает этот режим выбора. Существуют следующие девять режимов работы блока TRANSFER:
Операнд А может принимать указанные выше значения, а также может быть именем, положительным целым числом, выражением в скобках, СЧА, СЧА*параметр.
Операнды B и С задают возможные значения номеров следующих блоков или их положение. Они могут быть такими же, как и операнд А. Использование этих значений будет описано ниже при рассмотрении указанных выше режимов работы. Если операнд B опущен, то планировщик записывает вместо него номер блока, следующего за блоком TRANSFER.
Рассмотрим режимы безусловной передачи и статистической передачи блока TRANSFER, как наиболее часто используемые в моделях.
Режим безусловной передачи. B режиме безусловной передачи операнд А не используется. Операнд B указывает имя блока, в который транзакт должен попытаться войти. Блок TRANSFER не может отказать транзакту во входе.
Например:
TRANSFER ,Oper
После входа транзакт сразу же пытается войти в блок с меткой Oper. Если этот блок отказывает во входе, транзакт остается в блоке TRANSFER.
Рассмотрим еще один пример использования безусловного режима блока TRANSFER. Пусть требуется поток обслуженных транзактов перед удалением из модели разделить на четыре составляющие. Первый параметр каждого транзакта имеет одно из четырех присвоенных ранее значений: 1, 2, 3 или 4. Вначале для разделения потока используем блок TEST.
. . . TEST EP1,1,Met2 Met2 TERMINATE TEST EP1,2,Met3 TERMINATE Met3 TEST EP1,3,Met4 TERMINATE Met4 TERMINATE
Теперь этот же фрагмент модели перепишем с использованием блока TRANSFER.
. . . Met1 TRANSFER ,(Met1+P1) TERMINATE TERMINATE TERMINATE TERMINATE
В блоке TRANSFER в качестве операнда B указано выражение в скобках. При входе активного транзакта выражение вычисляется, т. е. к номеру, который присвоен планировщиком блоку с меткой Met1, прибавляется значение первого параметра. В итоге получается номер блока, к которому и направляется транзакт.
Режим статистической передачи. Когда операнд А используется и не является зарезервированным словом, блок TRANSFER работает в режиме передачи транзакта в один из двух блоков случайным образом.
Значение операнда А, записываемого после точки, рассматривается как трехзначное число, показывающее (в долях от тысячи), какая доля входящих в блок транзактов должна быть направлена в блок С. Остальные транзакты направляются в блок B или к следующему по номеру блоку, если операнд B опущен.
Числовое значение операнда А может быть задано любым СЧА. При этом возможны следующие случаи:
Если вычисленное значение операнда А меньше или равно нулю, то будет производиться безусловная передача транзакта к блоку B. Если значение операнда А больше или равно 1 000, то будет осуществляться безусловная передача транзакта к блоку С. В третьем случае блок TRANSFER работает в обычном режиме.
Например:
TRANSFER .P5,,Rrw
Трехзначное число, записанное в параметре 5 транзакта, входящего в блок TRANSFER, интерпретируется как вероятность (в долях от тысячи) того, что транзакт будет передаваться блоку Rrw, а в остальных случаях - следующему блоку, так как операнд B не используется.
Режим статистической передачи удобно использовать, например, в таких случаях. При моделировании работы цеха по производству деталей известно, что 12,5% изготовленных деталей бракуется. В модели это можно реализовать так:
. . . TRANSFER .125,Sam,Wzw . . .
Транзакты, имитирующие изготовленные в цехе детали, в 12,5% случаев будут направлены к блоку с
меткой Wzw, а в остальных 87,5% случаях - к блоку с меткой Sam.
Можно указать генератор - источник случайных чисел. Для этого нужно выбрать Edit/Settings ( Правка/Настройки ). Затем выбрать страницу Random Numbers ( Случайные числа ) и ввести номер генератора в поле ввода, отмеченное TRANSFER. После инсталляции по умолчанию используется генератор номер 1.
Блок DISPLACE предназначен для нахождения любого тран-закта и перемещения его к новому блоку. Блок DISPLACE имеет формат:
DISPLACE A,B,[C],[D]
Операнд А - номер транзакта, который нужно переместить.
Операнд B - метка блока, к которому перемещается транзакт, указанный операндом А.
Операнд С - номер параметра перемещаемого транзакта, в который записывается оставшееся до конца его обслуживания время, если он находился в списке будущих событий.
Операнд D - метка альтернативного блока для транзакта.
Операнды А, B, С и D могут быть именем, положительным целым числом, выражением в скобках, СЧА или СЧА*параметр. Например:
DISPLACE (P2+32),Term3,Ostatok,Met2
Операнд А указан выражением в скобках. Это выражение вычисляется и округляется до целого. Полученный результат является номером транзакта, который следует переместить. Далее блок DISPLACE отыскивает этот транзакт. При этом возможны случаи:
Term3. Во втором случае определяется время, оставшееся до его повторного ввода в процесс моделирования, и записывается в параметр с именем Ostatok. Если параметра с таким именем нет, он создается. Транзакт также перемещается к блоку с меткой Term3. В третьем случае, т. е. когда в модели нет транзакта с нужным номером, активный транзакт, вошедший в блок DISPLACE, направляется к блоку с меткой Met2. Если операнда D нет, активный транзакт переходит к следующему блоку.
Когда транзакт перемещается к новому блоку, он исключается из списков:
При перемещении прерванные выполнения в устройствах не сбрасываются.
Это означает, что перемещаемый транзакт продолжает занимать устройство. Следовательно, если необходимо, нужно освободить устройство.
Пример использования блока DISPLACE приведен в п. 6.8.2.
Если на входе ОКУ образуется очередь, выбор транзакта для ОКУ занятия после его освобождения происходит:
При этом очередной транзакт с большим приоритетом ждет окончания обслуживания предыдущего транзакта независимо от его приоритета. Приоритет учитывается только в образующейся очереди. В ней транзакты выстраиваются в приоритетном порядке.
Такой режим функционирования ОКУ организуется блоками SEIZE и RELEASE, рассмотренными в п. 6.2.2.
Однако может возникнуть необходимость смоделировать ситуацию, когда очередной транзакт должен занять ОКУ, прервав обслуживание предыдущего транзак-та. Такое прерывание называется "захватом" ОКУ и моделируется блоком PREEMPT (захватить). Формат блока:
PREEMPT A,[B],[C],[D],[E]
Операнд А - имя или номер захватываемого ОКУ.
Когда ОКУ свободно (см. блок-диаграмму), блок PREEMPT работает также, как и блок SEIZE.
При занятом ОКУ блок PREEMPT функционирует либо в приоритетном режиме, либо в режиме прерывания. Режимы определяются операндом B:
В приоритетном режиме прервать обслуживание предыдущего (обслуживаемого) транзакта, т. е. "захватить" ОКУ, может только транзакт с большим приоритетом. Если приоритет претендующего на занятие ОКУ транзакта равен или ниже приоритета обслуживаемого транзакта, он помещается в список задержки ОКУ последним в своем приоритете.
Что делать с транзактом, обслуживание которого прерывается? Это определяют операнды С, D и Е.
Операнд С - имя или номер блока, куда должен быть направлен прерванный транзакт.
Операнд Е при значении RE определяет режим удаления прерванного транзакта.
Операнд D - номер параметра прерванного транзакта, в который записывается оставшееся до завершения обслуживания время.
Операнды А, С, D и Е могут быть именем, положительным целым числом, выражением в скобках, СЧА или СЧА*параметр.
Транзакт, захвативший ОКУ, освобождает его от захвата вхождением в блок RETURN.Формат блока:
RETURN A
Операнд А - имя или номер освобождаемого ОКУ. Например:
RETURN Rem1
Освободить от захвата ОКУ Rem1.
Применение блоков PREEMPT и RETURN показано в п. 6.5.5.
В режиме "захвата", если ОКУ уже используется, активный транзакт помещается в список отложенных прерываний или "захватывает" ОКУ. Прерывание обслуживания сразу, а не помещение транзакта в список, происходит тогда, когда список отложенных прерываний пуст и обслуживаемый транзакт сам не является "захватчиком".
Транзактам из списка отложенных прерываний предоставляется право занять ОКУ ранее, чем прерванным транзактам или транзак-там из списка задержки ОКУ.
Проверка состояния ОКУ в приоритетном режиме может проводиться блоком GATE, а также с использованием булевой переменной и блока TEST.
Рассмотрим проверку состояния ОКУ блоком GATE.
Условие проверки задается одним из следующих условных операторов Х:
Например:
GATE I Stan GATE NI (V$Rasp-3) GATE I Print,Udal GATE I *1
В первом примере блок GATE пропустит транзакт, когда ОКУ Stan будет прервано. Во втором примере транзакт пройдет к следующему блоку, когда не прервано ОКУ, номер которого определяется как результат вычисления и последующего округления до целого выражения в скобках ( V$Rasp-3 ). В третьем примере в случае прерывания ОКУ Print транзакт будет направлен к блоку с меткой Udal.
В первом и втором примерах блок GATE работает в режиме отказа во входе в случае невыполнения условия. Здесь также остается справедливым замечание, сделанное в п. 6.2.4: отсутствие операнда В может привести к увеличению машинного времени моделирования. Однако в некоторых случаях такой режим, наверное, можно использовать.
Для моделирования неисправностей ОКУ и других ситуаций в GPSS World предусмотрены блоки, реализующие недоступность и доступность ОКУ. При использовании этих блоков статистика ОКУ не искажается. Здесь имеется в виду следующее. Для моделирования, например, неисправностей можно использовать и режим прерывания ( PREEMPT ). Однако при этом транзакты, вызывающие прерывания (имитирующие отказы ОКУ), учитываются в статистике, как и транзакты, обслуженные при исправном функционировании ОКУ. А это неправильно, вследствие чего и искажается статистика ОКУ.
Недоступность ОКУ моделируется блоком FUNAVAIL (символ F означает ОКУ, UNAVAIL - недоступный). При использовании этого блока статистика ОКУ не искажается.
Формат блока:
FUNAVAIL A,[B],[C],[D],[E],[F],[G],[H]
Блок делает недоступным ОКУ с именем или номером, указываемым операндом А (см. блок-диаграмму).
Все транзакты, обрабатываемые блоком FUNAVAIL, разделяются на три класса, которые и определяют назначение операндов:
Операндом B задаются режимы обработки транзакта, занимающего ОКУ в момент перевода его в недоступноcть:
Операнд С - метка блока, в который будет направлен в режиме удаления транзакт, занимавший ОКУ в момент перевода его в недоступное состояние.
Операнд D - номер или имя параметра транзакта, занимавшего ОКУ в момент перевода его в недоступное состояние; если он будет удален (режим RE ), т. е. исключен из СБС, в этот параметр будет записано время, оставшееся удаленному транзакту до конца обслуживания.
Операндом Е задаются режимы обработки транзактов, находящихся к моменту перевода ОКУ в недоступное состояние в списке прерываний, т. е. тех транзактов, обслуживание которых на данном ОКУ было ранее прервано:
Операнд F указывает метку блока, к которому будут направлены транзакты из списка прерываний ОКУ, из-за чего они не могут находиться в СБС, поэтому для них нет возможности занесения в их параметры времени, оставшегося до конца обслуживания.
Операнд F может использоваться и тогда, когда отсутствует операнд E (по умолчанию). В этом случае для перемещенных к новому блоку транзактов прерывание обслуживания сохраняется.
Операндом G задаются режимы обработки транзактов, находящихся к моменту перевода ОКУ в недоступное состояние в списке отложенных прерываний, т. е. ожидающих выполнения с прерыванием, и в списке задержки:
Операндом H указывается метка нового блока, к которому в режиме удаления ( RE ) направляются транзакты из списка отложенных прерываний и списка задержки. Когда операнд G не используется, нельзя использовать и операнд H.
Недоступность ОКУ сохраняется до тех пор, пока транзакт, вызвавший переход в недоступное состояние, не войдет в блок
FAVAIL A
Блок FAVAIL изменяет состояние ОКУ на доступное, т. е. восстанавливает обычный режим вхождения транзактов в ОКУ. Все транзакты, ожидающие доступного состояния ОКУ, указанного операндом А, активизируются и могут попытаться занять его.
Применение блоков FUNAVAIL и FAVAIL показано в п. 6.7.5.
Проверка состояния ОКУ в режиме недоступности проводится блоком GATE. Формат блока см. п. 6.2.4.
Условие проверки задается одним из следующих условных операторов Х:
FNV - ОКУ, заданное операндом А, недоступно ;
FV - ОКУ, заданное операндом А, доступно.
Например:
GATE FNV Stan GATE FV (FN$Rasp-X$Col) GATE FNV Print,Udal
В первом примере блок GATE пропустит транзакт, когда ОКУ Stan будет недоступно.
Во втором примере транзакт пройдет к следующему блоку, когда доступно ОКУ, номер которого определяется как результат вычисления и последующего округления до целого выражения в скобках (FN$Rasp-X$Col).
В третьем примере в случае доступности ОКУ Print, т. е. не выполнения заданного в блоке GATE условия, транзакт будет направлен к блоку с меткой Udal.
В первом и втором примерах блок GATE работает в режиме отказа, если условия не выполняются. Здесь также остается справедливым замечание, сделанное в п. 6.2.4: отсутствие операнда В может привести к увеличению времени моделирования.
При движении по модели транзакты могут быть заблокированы, например, как отмечалось ранее, при проверке состояния ОКУ блоками GATE и TEST. Если заблокированные транзакты находятся в списке текущих событий (СТС), то при большом их количестве планировщик расходует много времени на просмотр СТС с целью выбора очередного транзакта для продвижения.
Для экономии машинного времени заблокированные транзакты целесообразно помещать в списки пользователя и оставлять их там до тех пор, пока не будут выполнены условия, позволяющие дальнейшее продвижение этих транзактов. Кроме того, этим предоставляется возможность организовать различные дисциплины очередей, отличающиеся от дисциплины FIFO, реализованной в списке текущих событий.
Список пользователя представляет собой некоторый буфер, в который могут временно помещаться транзакты, выведенные из СТС. В отличие от списков текущих и будущих событий тран-закты вводятся в список пользователя и выводятся из него не автоматически, а по решению пользователя в соответствии с логикой модели при помощи специальных блоков.
Для ввода транзактов в список пользователя служит блок LINK (ввести в список), который может быть использован в режимах:
В безусловном режиме, блок LINK имеет формат записи: [имя] LINK A,B
Операндом А задается имя или номер списка пользователя, в который безусловно помещается транзакт, вошедший в блок LINK.
Операнд B определяет, в какое место списка пользователя следует поместить вошедший транзакт. Допустимые значения:
В качестве операнда B могут использоваться и другие СЧА, кроме указанных ранее СЧА транзактов: арифметическая переменная, функция, а также выражение в скобках. В этом случае выполняется вычисление указанного операндом B для активного транзакта и для всех остальных транзактов, уже находящихся в списке пользователя, начиная с начала очереди. После этого производится упорядочивание транзактов в списке пользователя по убыванию вычисленного значения. Например, блок
LINK 3,FIFO
помещает транзакты в конец списка пользователя с номером 3 в порядке их поступления в блок. Блок
LINK Otst,P$Pol
помещает транзакты в список пользователя с именем Otst, упорядочивая их по возрастанию значения параметра с именем Pol.
Условия, при которых транзакт помещается в список пользователя, в безусловном режиме проверяются средствами, предусмотренными разработчиком модели. Например, направить транзакт в список пользователя в случае занятости ОКУ можно так, как показано ниже.
. . . GATE NU Rem1,Wait SEIZE Rem1 . . . Wait LINK Otst,FIFO . . .
Если ОКУ Rem1 занято, блок GATE не впускает транзакт в блок SEIZE, а направляет его в блок LINK с именем Wait, и тран-закт вводится в конец списка пользователя с именем Otst.
В том же фрагменте модели список пользователя можно разместить и иначе.
. . . GATE U Rem1,Met1 LINKOtst,FIFO Met1 SEIZE Rem1 . . .
Здесь ОКУ Rem1 проверяется на занятость. Если ОКУ занято, транзакт проходит к следующему блоку LINK и помещается в список пользователя с именем Otst. В случае незанятости ОКУ, транзакт направляется к блоку SEIZE с меткой Met1 и занимает свободное ОКУ.
В только что рассмотренных примерах предполагается, что список пользователя неограничен, т. е. в него может помещаться любое количество транзактов. При моделировании реальных систем список пользователя может использоваться для имитации, например, входного накопителя, емкость которого, как правило, ограничена. Это ограничение можно реализовать следующим образом.
Emk EQU10 . . . GATE NU Rem1,Wait SEIZE Rem1 . . . Wait TEST L CH$Otst,Emk,Term1 LINK Otst,LIFO
Если ОКУ Rem1 занято, то блок GATE не впускает транзакт в блок SEIZE, а направляет его в блок TEST с меткой Wait, находящийся перед блоком LINK. Если текущее содержимое списка пользователя с именем Otst меньше заданной емкости Emk, тран-закт проходит в список пользователя, в противном случае направляется к блоку с меткой Term1.
Приведем еще возможный вариант этого же фрагмента модели.
Emk EQU 10 . . . GATE U Rem1,Met1 TEST L CH$Otst,Emk,Term1 LINK Otst,LIFO Met1 SEIZERem1
Если ОКУ Rem1 занято, блок GATE пропускает транзакт к блоку TEST. Если текущее содержимое списка пользователя с именем Otst меньше заданной емкости Emk, транзакт проходит в список пользователя, в противном случае направляется к блоку с меткой Term1. Если ОКУ незанято, транзакт направляется к блоку SEIZE с меткой Met1 и занимает свободное ОКУ Rem1.
Для вывода одного или нескольких транзактов из списка пользователя и помещения их обратно в список текущих событий служит блок UNLINK (вывести из списка), имеющий следующий формат:
[имя] UNLINK X A,B,C,[D],[E],[F]
Операндом А указывается имя или номер списка пользователя.
Операнд B - метка блока, в который переходят выведенные из списка пользователя транзакты.
Операндом С указывается число выводимых транзактов или ключевое слово ALL для вывода всех находящихся в списке транзактов. По умолчанию, т. е. когда не используется операнд С, берется слово ALL.
Операнды D и E вместе с условным оператором Х определяют способ и условия вывода транзактов из списка пользователя. Значения оператора Х те же, что и в блоке TEST. В случае, когда условный оператор Х должен использоваться, но не указан, по умолчанию он принимает значение Е (равенство). Если операнды D и Е не используются, не указывается и условный оператор Х. В этом случае транзакты выводятся с начала списка, а количество выводимых транзактов определяется обязательным операндом С.
Операнд D может быть:
Если операнд D является булевой переменной, операнд Е и оператор Х не используются. Булева переменная вычисляется относительно транзакта, находящегося в списке пользователя. Если результат не нуль, т. е. условие вывода выполняется, транзакт выводится. Количество выводимых транзактов определяется операндом С. Однако выведено может быть и меньше, чем указано операндом С: по числу не нулевых результатов вычисления булевой переменной. Кроме того и транзактов в списке пользователя может быть меньше, чем указано операндом С.
Если операндом D указано ключевое слово BACK, также операнд Е и условный оператор Х не используются, а транзакты выводятся с конца списка в количестве, определяемом обязательным операндом С.
Если операнд D не булева переменная и не ключевое слово BACK, должны быть указаны операнд Е и условный оператор Х. Операнд D вычисляется относительно транзакта, находящегося в списке пользователя, и используется в качестве номера параметра, значение которого сравнивается с результатом вычисления операнда Е.
Если операнд D задает параметр, а операнд Е не используется, значение параметра транзакта из списка пользователя сравнивается со значением такого же параметра выводящего транзакта. Если они равны, транзакт выводится из списка пользователя. И в этом случае количество выводимых транзактов определяется операндом С.
Операндом F указывается имя блока, куда переходит транзакт, выходящий из блока UNLINK, если из списка пользователя не выведен ни один транзакт. Если операнд F не используется, выходящий транзакт переходит в следующий блок независимо от количества выведенных транзактов.
Например, блок
UNLINK 4,Apd,1
выводит из списка пользователя с номером 4 один транзакт с начала списка и направляет его в блок с меткой Apd. Блок
UNLINK Otst,Mars,1,BACK
выводит из списка пользователя с именем Otst один транзакт с конца списка и направляет его в блок с меткой Mars. Блок
UNLINK E P$Wiw,App1,ALL,App2,P$App2,App3
выводит из списка пользователя, номер которого записан в параметре Wiw выводящего транзакта, и направляет в блок с меткой App1 все транзакты, содержимое параметра App2 которых равно содержимому одноименного параметра выводящего транзакта. Если таких параметров в списке не окажется, выводящий транзакт будет направлен в блок с меткой Аpp3, в противном случае - к следующему блоку.
Примеры применения списков пользователя (блоков LINK и UNLINK ) показаны в п. 6.3 и 6.7.
Два или более обслуживающих устройств могут быть промоделированы на GPSS двумя или более ОКУ, располагаемыми рядом, т. е. параллельно. Так нужно поступать, когда отдельные устройства являются разнородными, т. е. характеризуются различными свойствами, например, различной интенсивностью обслуживания.
Однако часто различные параллельно работающие устройства являются однородными. GPSS представляет для моделирования однородных параллельных устройств специальное средство, именуемое многоканальным устройством. МКУ может быть использовано несколькими транзактами одновременно. Ограничений на число МКУ в модели нет. Для различия им дают имена.
МКУ определяется до его использования командой STORAGE. Формат команды:
Name STORAGE A
Name - имя МКУ. Символическому имени может быть поставлен в соответствие номер командой EQU. Это необходимо, если требуется обращаться к нескольким МКУ в блоках SELECT и COUNT или в других случаях. Операнд А может быть только целым положительным числом. Иные способы задания емкости вызывают ошибку.
В модели можно организовать функционирование МКУ в двух режимах:
Занятие и освобождение МКУ имитируется блоками ENTER (войти) и LEAVE (выйти). Форматы блоков:
ENTER A,[B] LEAVE A,[B]
Операнд А в обеих блоках используется для указания имени, соответствующего МКУ. Операнд B задает число устройств (элементов памяти), которое должно быть занято в блоке ENTER или освобождено в блоке LEAVE. По умолчанию операнд В = 1. При В = 0 блок считается неработоспособным.
Когда транзакт входит в блок ENTER, операнд А используется для нахождения МКУ с указанным именем. Если такого МКУ нет, происходит останов по ошибке "Обращение к несуществующей памяти". Если МКУ существует и задан операнд B, он вычисляется, округляется до целого и полученный результат используется для оценки свободной емкости. Транзакт может войти в блок ENTER, если МКУ находится в доступном состоянии и достаточно емкости для выполнения запроса. В противном случае транзакт помещается в список задержки устройства в соответствии с приоритетом.
Когда транзакт входит в блок ENTER (см. блок-диаграмму), планировщик выполняет следующие действия:
Если транзакт при входе в блок ENTER запрашивает больше устройств (элементов памяти), чем определено командой STORAGE, т. е. ее операнд А меньше операнда B блока ENTER, возникает ошибка "Запрос элементов памяти превышает ее общую емкость".
МКУ никогда не может быть удалено из текущей модели, даже если команда STORAGE удаляется из рабочей программы. МКУ можно переопределить, т. е. изменить емкость другой командой STORAGE с тем же самым именем. Например:
Batr STORAGE 18
Повторное описание:
Batr STORAGE 24
Имитация обслуживания транзакта в течение какого-то промежутка времени также осуществляется блоком ADVANCE.
Пример 1.
Nak STORAGE 20 . . . ENTER Nak,2 ADVANCE 120,40 LEAVE Nak,2 . . .
Командой STORAGE определяется МКУ с именем Nak емкостью 20 единиц. При входе транзакта в блок ENTER занимается 2 единицы и столько же освобождается в блоке LEAVE при выходе из МКУ.
Пример 2.
Nak STORAGE 20 . . . ENTER Nak,21 ADVANCE 120,40 LEAVE Nak,2 . . .
При входе транзакта в блок ENTER произойдет останов по ошибке, так как транзакт будет пытаться занять больше каналов (21), чем определено (20) командой STORAGE. То же самое произойдет, если при выходе из блока LEAVE транзакт будет пытаться освободить каналов больше, чем определено командой STORAGE.
Пример 3.
Pun1 EQU1 Pun2 EQU2 Pun3 EQU3 Pun1 STORAGE 6 Pun2 STORAGE 5 Pun3 STORAGE 3 . . . ENTER *1 ADVANCE MX$NorVr(P2,P3) LEAVE*1 . . .
В данном примере определены три МКУ с именами Pun1, Pun2, Pun3 и емкостями 6, 5 и 3 соответственно. Именам командами EQU поставлены в соответствие номера 1, 2 и 3.
Предполагается, что при входе транзакта в блок ENTER в его первом параметре (ссылка *1) содержится какой-либо один из трех номеров. Согласно этому номеру и занимается МКУ, а затем освобождается. Операнд B в блоках ENTER и LEAVE не используется, поэтому транзактом занимается и освобождается одна единица емкости МКУ.
Ранее (см. табл. 6.1) для МКУ был употреблен термин "память". Это связано с тем, что блоки ENTER и LEAVE могут быть использованы для имитации функционирования запоминающих устройств, например, оперативного или внешних устройств памяти. В этом случае в качестве операнда B этих блоков может быть использован один из параметров транзакта, имитирующего, например, сообщение, содержащий количество занимаемых (освобождаемых) ячеек памяти. Пример такого использования блоков ENTER и LEAVE приведен в 6.7.5.
Недоступность МКУ моделируется блоком SUNAVAIL (символ S означает МКУ, UNAVAIL - недоступный). Формат блока:
SUNAVAIL A
Операнд А - имя или номер МКУ, может быть именем, положительным целым числом, выражением в скобках, СЧА, СЧА*параметр.
Например:
SUNAVAIL Batr
Когда транзакт входит в этот блок, МКУ Batr становится недоступным. Если при переводе в недоступное состояние в МКУ находились транзакты, т. е. текущее содержимое МКУ не равнялось нулю, то обслуживание этих транзак-тов продолжается, пока текущее содержимое не станет равным нулю.
Транзакты, которые пытаются занять МКУ во время нахождения его в недоступном состоянии, не входят в блок ENTER и помещаются в список задержки МКУ.
Нахождение в недоступном состоянии продолжается до тех пор, пока транзакт не войдет в блок SAVAIL.
Формат блока:
SAVAIL A
Операнд А - имя или номер МКУ. Может быть таким же, как операнд А в блоке SUNAVAIL.
Если в момент перевода МКУ в доступное состояние в его списке задержки были транзакты, им предоставляется возможность занять МКУ в соответствии с дисциплиной "first-fit-with-skip" (первый подходящий с пропусками).
Транзакты, которым будет отказано в занятии МКУ, остаются в его списке задержки.
Состояние МКУ, как и состояние ОКУ, проверяется блоком GATE такого же формата
GATE X A,[B]
Отличие состоит в значениях условного оператора Х, которые могут быть следующими:
Например:
GATE SNF Can,Met5
Если МКУ с именем Can не заполнено, т. е. имеются свободные каналы (элементы памяти), заданное в блоке GATE условие выполняется, и транзакт будет направлен к следующему блоку. Если МКУ заполнено, транзакт будет направлен к блоку с меткой Met5.
Блок GATE позволяет только определить состояние не заполненности МКУ, т. е. наличие свободных каналов, но достаточно ли их для удовлетворения запроса, он не определяет.
Для проверки состояния МКУ могут также использоваться булева переменная и блок TEST [5]. Их использование позволяет расширить возможности по осуществлению проверок состояния, а также сократить машинное время, так как в одном блоке с помощью булевой переменной может проверяться сразу несколько условий.
Для моделирования такого оборудования как переключатели, имеющие только два состояния, в GPSS используются логические ключи. Логический ключ может находиться в одном из двух состояний:
Логический ключ моделируется блоком LOGIC. Формат блока:
LOGIC X A
Операнд А - имя или номер логического ключа. Может быть именем, положительным целым числом, выражением в скобках, СЧА или СЧА*параметр.
Логический оператор Х - состояние логического ключа устанавливается в зависимости от следующих его значений:
Состояние логического ключа проверяется также блоком GATE. Блок GATE имеет такой же формат, как и при проверке состояний ОКУ и МКУ, и два режима работы:
GATE X A,[B]
Операнд А - имя или номер проверяемого ключа. Может быть именем, положительным целым числом, выражением в скобках, СЧА или СЧА*параметр.
Операнд B - метка блока, к которому будет направлен тран-закт при невыполнения условия, заданного оператором Х.
Условный оператор может принимать значения: