Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции - Основы GPSSPC.doc
Скачиваний:
74
Добавлен:
02.05.2014
Размер:
425.98 Кб
Скачать

3. Логика работы интерпретатора gpss/pc.

Суть моделирования на языке GPSS/PC – это продвижение транзактов от одного блока к другому. Когда движение данного транзакта блокируется, интерпретатор берется за продвижение другого транзакта. При этом возникают вопросы: когда, какой и куда транзакт двигается? когда, как и где его продвижение приостанавливается? На все эти вопросы легко ответить, если понять логику работы интерпретатора GPSS/PC.

Как известно, интерпретатор GPSS/PC рассматривает каждый транзакт как элемент одного или более списков. Одновременно транзакт является элементом того или иного блока, где он находится в данный момент.

С каждым транзактом связано множество параметров, в том числе: номер транзакта; время движения; номер текущего блока; уровень приоритета; номер следующего блока. Эти параметры далее запишем в виде вектора описания транзакта. Например, вектор [10, 510, 5, 0, 6] определяет транзакт с номером 10 и с нулевым уровнем приоритета, который находится в блоке с номером 5 и планирует войти в блок с номером 6 в 510 единиц модельного времени.

Работа интерпретатора GPSS/PC состоит в реализации трех фаз:

1) фазы ввода;

2) фазы коррекции таймера модельного времени;

3) фазы просмотра списка текущих событий.

Суть каждой фазы работы интерпретатора поясним на примере модели на рис.9 из двух сегментов (один сегмент – модель, что на рис. 7а, а второй – сегмент времени). Здесь блоки приведены с номерами (не путать с номерами строк). Время моделирования – 1000 единиц модельного времени.

1 GENERATE 70,20

2 QUEUE OCH

3 SEIZE PRIBOR

4 DEPART OCH

5 ADVANCE 50,30

6 RELEASE PRIBOR

7 TERMINATE

8 GENERATE 1000

9 TERMINATE 1

Рис.10.

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

Таблица

Состояния списков текущих и будущих событий

модельное время

список текущих событий

список будущих событий

1

0

пусто

пусто

2

0

пусто

[1,80,–,0,1], [2,1000,–,0,8]

3

80

[1,КМР,–,0,1]

[2,1000,–,0,8]

4

80

пусто

[3,140,–,0,1], [1,150,5,0,6], [2,1000,–,0,8]

5

140

[3,КМР,–,0,1]

[1,150,5,0,6], [2,1000,–,0,8]

6

140

[3,КМР,2,0,3]

[1,150,5,0,6], [4,195,–,0,1], [2,1000,–,0,8]

7

150

[3,КМР,2,0,3], [1,КМР,5,0,6]

[4,195,–,0,1], [2,1000,–,0,8]

8

150

пусто

[4,195,–,0,1], [3,195,5,0,6], [2,1000,–,0,8]

9

195

[4,КМР,–,0,1], [3,КМР,5,0,6]

[2,1000,–,0,8]

10

196

пусто

[4,260,5,0,6], [5,270,–,0,1], [2,1000,–,0,8]

n-1

<1000

[…], […], …, […]

[2,1000,–,0,8], […], …, […]

n

1000

[…], […],…, […], [2,КМР,–,0,8]

n+1

1000

[…], …, […]

[…],[…] ,…, [k,2000,–,0,8]

Фаза ввода.

Фаза ввода начинается с момента загрузки программы в поле данных интегрированной среды. Перед фазой ввода в модели нет ни одного транзакта, все списки пусты, таймер модельного времени установлен в 0 (строка 1 таблицы). При вводе (трансляции) программы (последовательно оператор за оператором) интерпретатор проверяет все операторы на наличие синтаксических ошибок и каждый раз, когда встречает блок GENERATE планирует приход первого транзакта в данный блок в соответствии с его операндами А, В или С. В нашем примере первым таким блоком является блок GENERATE 70,20 (блок 1), который задает равномерный на отрезке [50, 90] закон распределения интервалов прихода транзактов. Интерпретатор разыгрывает (соответствующая процедура рассматривается в разделе 4) случайный интервал прихода транзакта. Пусть он равен 80. Тогда момент прихода первого транзакта (это будет транзакт с номером 1) в блок GENERATE также будет равен 80, т.к. текущий момент модельного времени равен 0. С этим запланированным временем движения транзакт 1 помещается интерпретатором в список БС.

Точно также поступает интерпретатор, когда встречает другой блок GENERATE 1000 (блок 8), который определяет детерминированный закон поступления транзактов. Очевидно, что момент прихода первого транзакта (это будет транзакт 2) в этот блок равен 1000 и с этим временем движения интерпретатор помещает транзакт 2 в список БС вслед за транзактом 1.

Состоянию модели после фазы ввода соответствует строка 2 в таблице состояний списков. Заметим, что в позициях текущего блока векторов описания транзактов 1 и 2 стоят прочерки, поскольку эти транзакты все еще находятся в буфере пассивных транзактов (на пути в модель), пребывая в списке БС.

После фазы ввода интерпретатор должен перейти к реализации фазы коррекции таймера модельного времени, т.е. приступить непосредственно к моделированию. Однако, это произойдет только если в программе или с командной строки будет задан управляющий оператор START, например, START 1. При этом значение 1 операнда А этого оператора интерпретатор заносит в счетчик завершений и приступает к прогону модели.

Фаза коррекции таймера модельного времени (первая реализация).

Интерпретатор просматривает список БС и устанавливает таймер в значение 80 – ближайший запланированный момент движения транзакта (транзакт 1), находящийся в начале списка БС. Затем он перемещает транзакт 1 в пустой прежде список ТС. Если в списке БС есть еще транзакты с запланированным временем движения, равным 80, интерпретатор также перемещает их в список ТС. Однако в нашем примере следующий транзакт (транзакт 2) в списке БС имеет отличное от 80 значение времени движения.

На этом завершается первая реализация фазы коррекции таймера и состоянию модели в данный момент соответствует строка 3 таблицы состояний списков.

После того как для транзакта наступило запланированное время его движения, и он оказался в списке ТС, то главная цель транзакта состоит как можно раньше (КМР) продвинуться вперед, т.е. войти в следующий блок. Поэтому в списке ТС все транзакты в позиции время движения вектора состояния имеют запись КМР (в том числе и транзакт 1 в строке 3). Кроме того, позиция текущего блока для транзакта 1 по-прежнему содержит прочерк, поскольку он еще не вошел в блок 1. Это произойдет только после просмотра списка ТС.

Фаза просмотра списка текущих событий (первая реализация).

Выбрав транзакт 1 в начале списка ТС, интерпретатор перемещает его в блок 1 (блок GENERATE) и вектор его состояния в этот момент примет вид [1, КМР, 1, 0, 2]. Затем интерпретатор проверяет сможет ли транзакт 1 войти в следующий блок 2 – блок QUEUE. Блок QUEUE никогда не отказывает транзакту во входе и поэтому попытка входа будет успешной. В момент выхода текущего транзакта из блока GENERATE интерпретатор временно приостанавливает его продвижение и планирует приход следующего транзакта в данный блок. Пусть второй розыгрыш случайного интервала прихода транзакта выдает значение 60. Тогда момент прихода второго транзакта (транзакт 3) в блок GENERATE 70,20 будет равен 140 – текущее значение таймера плюс значение интервала (80+60). С этим временем начала движения транзакт 3 интерпретатором помещается в списке БС, и он возобновляет прерванное движение транзакта 1.

Транзакт 1 перемещается в блок QUEUE (вектор состояния примет вид [1,КМР,2,0,3]), затем в блок SEIZE ([1,КМР,3,0,4]), DEPART ([1,КМР,4,0,5]) и ADVANCE. Напомним, что каждый раз, когда транзакт входит в тот или иной блок, интерпретатор вызывает соответствующую подпрограмму, которая выполняет предусмотренные при этом действия, в частности, увеличивает счетчик входов блока (как правило, на 1).

В блоке ADVANCE 50,30 (блок 5) разыгрывается случайное время задержки в нем в соответствии с равномерным распределением на отрезке [20,80]. Пусть это время будет 70. Тогда время выхода транзакта 1 из блока ADVANCE в блок RELEASE (блок 6) планируется на момент времени 150 (80+70) и с этим временем движения транзакт 1 помещается в список БС и его движение прекращается. Далее интерпретатор должен перейти к обработке других транзактов в списке ТС, но таких транзактов более нет.

На этом завершается первая реализация фазы просмотра списка ТС, и интерпретатор переходит ко второй реализации фазы коррекции таймера. Состоянию модели в этот момент соответствует строка 4 в таблице состояний списков. Заметим, что на фазе просмотра списка ТС модельное время не изменилось, т.е. все действия на данной фазе интерпретатор реализовал в одно то же значение модельного времени.

Фаза коррекции таймера (вторая реализация).

Интерпретатор продвигает таймер к значению 140 – запланированное время движения транзакта 3 в начале списка БС. Далее он перемещает транзакт 3 в пустой прежде список ТС и смотрит, есть ли в списке БС еще транзакты со временем движения, равным 140. Поскольку таких транзактов более нет, то на этом завершается вторая реализация фазы коррекции таймера и интерпретатор вновь переходит к реализацию фазы просмотра списка ТС. Состоянию модели в данный момент соответствует строка 5 таблицы состояний списков.

Фаза просмотра (вторая реализация).

Взяв транзакт 3 в начале списка ТС, интерпретатор перемещает его в блок 1 – блок GENERATE (вектор состояния примет вид [3,КМР,1,0,2]) и затем определяет, может ли он войти в следующий блок 2 – блок QUEUE. Поскольку это возможно интерпретатор, временно приостановив обработку транзакта 3 при его выходе из блока GENERATE, планирует приход следующего транзакта в данный блок. Это будет транзакт 4. Пусть случайный интервал прихода транзакта 4 будет равен 55. Тогда момент его входа в блок 1 будет 195 (140+55) и с этим временем начала движения транзакт 4 помещается в список БС. Потом интерпретатор, возобновляя прерванное движение транзакта 3, перемещает его в блок QUEUE ([3,КМР,2,0,3]). Далее транзакт 3 пытается выйти из блока QUEUE и войти в блок 3 - блок SEIZE. Однако устройство PRIBOR находится в состоянии “занято” (там “обслуживается” транзакт 1), поэтому вход в этот блок запрещен. Таким образом, транзакт 3 становится заблокированным, и интерпретатор оставляет его в блоке QUEUE и в списке ТС, планируя переместить в блок 3 как можно раньше.

Если бы в списке ТС были бы еще транзакты, то интерпретатор должен был их обработать. Но в данном случае таких транзактов более нет и поэтому интерпретатор переходит к фазе коррекции таймера (третий раз). Состоянию модели в этот момент соответствует строка 6 в таблице состояний списков.

Фаза коррекции (третья реализация).

Интерпретатор продвигает таймер модельного времени к значению 150 – времени движения транзакта 1 в начале списка и перемещает этот транзакт в список ТС, где он располагается за транзактом 3 согласно дисциплине FIFO среди транзактов одного уровня приоритета. Поскольку следующий транзакт в списке БС (транзакт 4) имеет значение 195 времени движения, то интерпретатор вновь переходит к просмотру списка ТС. Состоянию модели в этот момент соответствует строка 7 таблицы состояний списков.

Фаза просмотра (третья реализация).

Выбрав транзакт 3 из начала списка ТС, интерпретатор пытается вывести его из блока 2 и ввести в блок 3 (блок SEIZE), но эта попытка вновь окажется безуспешной, поскольку устройство все еще находится в состоянии “занято”. Таким образом, транзакт 3 опять остается в блоке 2 и в списке ТС, и интерпретатор переходит к обработке следующего транзакта в списке ТС – транзакт 1. Интерпретатор перемещает его из блока 5 (блок ADVANCE) в блок 6 (блок RELEASE) и далее – в блок 7 (блок TERMINATE), который удаляет его из модели и возвращает в буфер пассивных транзактов.

Следует особо отметить, что если при перемещении какого-нибудь транзакта по блокам модели, он входит в один из блоков SEIZE, RELEASE, ENTER или LEAVE, то интерпретатор после завершения движения данного транзакта, обязательно просматривает с начала список ТС. В нашем случае транзакт 1 входил в блок RELEASE (при этом устройство PRIBOR было переведено из состояния “занято” в состояние “свободно”), поэтому интерпретатор вновь просматривает список ТС. При этом транзакт 3 в этом списке снова попытается выйти из блока 2 и войти в блок 3, но на этот раз попытка, очевидно, окажется успешной. Далее он входит в блок DEPART (блок 4), а затем – в блок ADVANCE (блок 5), где разыгрывается время его задержки в нем. Пусть это время будет равно 45. Тогда запланированное время выхода транзакта 3 из блока 5 будет 195, и интерпретатор помещает его в список БС. Заметим, что в списке БС уже имеется транзакт 4 с тем же временем начала движения, поэтому транзакт 3 помещается позади него. Таким образом, транзакты 3 и 4 образуют временной узел.

Поскольку транзакт 3 прошел блок SEIZE (блок 3) интерпретатор заново просматривает список ТС, но на этот раз список пуст и он четвертый раз переходит к коррекции таймера. Состоянию модели в этот момент соответствует строка 8 таблицы состояний списков.

Фаза коррекции (четвертая реализация).

Интерпретатор продвигает модельное время к значению 195 – времени движения транзакта 4 в начале списка БС и перемещает этот транзакт в список ТС. Следующий транзакт в списке БС (транзакт 3) имеет такое же время начала движения, и поэтому он также перемещается в список ТС, где располагается следом за транзактом 4. Больше в списке БС нет таких транзактов и на этом завершается четвертая реализация фазы коррекции и состоянию модели при этом соответствует строка 9 таблицы.

Фаза просмотра (четвертая реализация).

Выбрав транзакт 4 из начала списка ТС, интерпретатор перемещает его в блок 1 и далее определяет можно ли его переместить из блока 1 в блок 2. Поскольку это возможно, то, временно приостановив движение транзакта 4 при его выходе из блока 1, интерпретатор планирует время прихода его последователя в блок GENERATE 70,20. Пусть это время будет 270 (предполагается, что разыгранное значение интервала прихода равно 75) и соответствующий транзакт (это будет транзакт 5) помещается в список БС. Далее транзакт 4 входит в блок 2 (блок QUEUE) и должен остаться там, т.к. блок SEIZE не может принять его.

Интерпретатор переходит к обработке транзакта 3, который последовательно входит в блоки RELEASE и TERMINATE и покидает модель. Поскольку произошел вход транзакта в блок RELEASE, интерпретатор заново просматривает список ТС. Транзакт 4 теперь уже может успешно войти в блок SEIZE, а далее – в блоки DEPART (перестает быть элементом очереди ОСН) и ADVANCE, где задерживается пусть до момента времени 260 (предполагается, что разыгранное время задержки равно 65) и с этим временем начала движения помещается в списке БС.

Поскольку транзакт 4 прошел блок SEIZE, то интерпретатор вновь просматривает список ТС. Однако он уже пуст и интерпретатор переходит к очередной реализации фазы коррекции таймера. Состоянию модели в этот момент соответствует строка 10 таблицы состояний списков.

При этой реализации фаз коррекции и просмотра ТС мы столкнулись с одновременными событиями: “приход заявки” (моделируется транзактом 4) и “окончание обслуживания” (моделируется транзактом 3), которые обрабатываются интерпретатором последовательно. В силу того, что в списке ТС транзакт 4 случайно оказался впереди транзакта 3, то сперва обрабатывается событие “приход заявки”, а затем – событие “окончание обслуживания” и, соответственно, поступившая заявка (транзакт 4) не может занять вроде бы уже свободный прибор. В данном примере это не имеет принципиального значения, а вот если бы мы моделировали СМО, где поступающая заявка, которая застает прибор занятым, покидает систему, то, очевидно, что транзакт 4 в таком случае был бы удален из модели. При таких условиях очень важно разработать модель таким образом, чтобы в случае возникновения временных узлов, событие “окончание обслуживания” всегда обрабатывалось раньше события “приход заявки”. Такая последовательность обработки достигается путем назначения более высокого приоритета транзакту “окончание обслуживания” по сравнению с транзактом “приход заявки” и тогда первый транзакт в списке ТС всегда будет впереди второго транзакта и соответственно всегда будет раньше обработан.

Интерпретатор поочередно реализует фазы коррекции таймера и просмотра списка ТС. Очевидно, в модели когда-нибудь возникнет ситуация, когда перед началом очередной реализации фазы коррекции таймера в начале списка БС окажется транзакт 2 (строка n-1 таблицы состояний списков). При данной коррекции модельное время принимает значение 1000 и транзакт 2 переносится в список ТС (строка n таблицы).

При последующем просмотре списка ТС после обработки всех транзактов, находящихся в списке ТС перед транзактом 2, интерпретатор начинает перемещение данного транзакта. Транзакт 2 входит в блок 8 (блок GENERATE 1000) и интерпретатор проверяет, может ли он войти в блок 9 (блок TERMINATE 1). Поскольку это возможно (блок TERMINATE – безотказный), при выходе транзакта 2 из блока GENERATE 1000 интерпретатор приостанавливает его движение и планирует приход его последователя в данный блок и помещает его в список БС с очевидным временем начала движения в 2000 (стока n+1 таблицы, номер данного транзакта предугадать невозможно).

Далее интерпретатор возобновляет движение транзакта 2, который входит в TERMINATE 1, где в операнде А задано значение 1. Это значение отнимается от текущего содержимого счетчика завершений, которое равно 1 (оно установ-лено в начале моделирования оператор START). Таким образом значение счетчика завершений становится равным 0 и моделирование завершается.