Списки пользователя используются для сокращения времени моделирования, а также для создания сложных дисциплин обслуживания.При движении по модели заявки могут быть заблокированы, например, при проверке состояния устройств операторами GATE и TEST. Если заблокированные заявки находятся в СТС, то при их большом количестве планировщик расходует много времени на просмотр СТС с целью выбора очередной заявки для продвижения. Для экономии машинного времени заблокированные заявки целесообразно помещать в списки пользователя и оставлять их там до тех пор, пока не будут выполнены условия, позволяющие их дальнейшее продвижение. Кроме того, размещение ожидающих заявок в списках пользователя позволяет организовать различные дисциплины очередей, отличающиеся от дисциплины FIFO (первым пришел – первым обслужен), реализованной в списке текущих событий.
Список пользователя представляет собой некоторый буфер, в который могут временно помещаться заявки, выведенные из СТС. В отличие от списков текущих и будущих событий заявки вводятся в список пользователя и выводятся из него не автоматически, а по решению пользователя в соответствии с логикой модели при помощи специальных операторов.
Для ввода заявок в список пользователя служит оператор LINK (ввести в список), который может быть использован в двух режимах: условном и безусловном.
LINK – ввод заявок в список пользователя. Рассмотрим безусловный режим, в котором оператор LINK имеет следующий формат записи:
[имя] LINK А,В
Операндом А задается имя или номер списка пользователя, в который безусловно помещается заявка, вошедший в оператор LINK. Операнд В определяет, в какое место списка пользователя следует поместить вошедшую заявку. Допустимые значения:
- FIFO – заявка помещается в конец списка;
- LIF0 – заявка помещается в начало списка;
- PR – заявки упорядочиваются по убыванию приоритета;
- Р – заявки помещаются позади тех заявок, значения соответствующего параметра которых меньше (в порядке возрастания);
- M1 – заявки помещаются в порядке возрастания относительного времени пребывания в модели.
В качестве операнда В могут использоваться и другие СЧА, кроме указанных СЧА заявок: арифметическая переменная, функция, а также выражение в скобках. В этом случае выполняется вычисление указанного операндом В для активной заявки и для всех остальных заявок, уже находящихся в списке пользователя, начиная с начала очереди. После этого производится упорядочивание заявок в списке пользователя по убыванию вычисленного значения. Например:
- 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
LINK Otst,FIFO
Met1 SEIZE Rem1
. . .
Здесь устройство Rem1 проверяется на занятость. Если устройство занято, заявка проходит к следующему оператору LINK и помещается в список пользователя с именем Otst. В случае незанятости устройства, заявка направляется к оператору SEIZE с меткой Met1 и занимает свободное устройство.
В рассмотренных примерах предполагается, что список пользователя неограничен. При моделировании реальных систем список пользователя может использоваться для имитации, например, входного накопителя, емкость которого ограничена. Это ограничение можно реализовать следующим образом:
Emk EQU 10
. . .
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.
Ввод заявок в список пользователя в условном режиме. Для ввода заявок в список пользователя используется оператор LINK формата:
[имя] LINK А,В,[C]
Операндом С указывается метка оператора, к которому переходит активная заявка в случае, если индикатор (флаг) списка пользователя установлен в 0 (выключен). Индикатор имеется у каждого списка пользователя. Когда операнд С не используется, т. е. оператор LINK работает в безусловном режиме, индикатор устанавливается в 1 (включается) и все вошедшие в оператор LINK заявки помещаются в список пользователя.
Рассмотрим использование списка пользователя в условном режиме:
. . .
LINK Nak,M1,Met1
Met1 SEIZE Can
ADVANCE V$Zad
RELEASE Can
UNLINK Nak,Met1,1
. . .
Заметим, что если бы оператор LINK в этом примере был использован без операнда С, то модель не работала бы, так как все заявки, входящие в оператор LINK, помещались бы в список пользователя и ни одна из них не попала бы в устройство Can.
В примере с использованием оператора С индикатор списка пользователя управляется операторами LINK и UNLINK (см. вывод заявок из списка пользователя). Если в операторе LINK используется операнд С, оператор UNLINK при обнаружении того, что список пользователя пуст, сбрасывает индикатор в 0 (выключает). Первая заявка, вошедший в оператор LINK, находит индикатор в выключенном состоянии, поэтому не помещается в список пользователя, а направляется к оператору сметкой Met1, указанной операндом С. После этого оператор LINK устанавливает индикатор в 1 (включает).
Следующая заявка может войти в оператор LINK либо раньше, чем тот закончит обслуживание предыдущей, либо после того, как это обслуживание завершится. Если следующий заявка войдет в оператор LINK раньше, чем будет закончено обслуживание в устройстве с именем Саn предыдущей заявки, она будет помещена в список пользователя. Если обслуживание предыдущей заявки закончится раньше, чем очередная заявка войдет в оператор LINK, то обслуженная заявка (она же выводящая) войдет в оператор UNLINK и будет обнаружено, что список пользователя пуст. Оператор UNLINK установит индикатор списка пользователя в 0 (выключит). Поэтому следующая заявка вновь будет направлен к оператору с меткой Met1, а не помещен в список пользователя.
Таким образом оператор LINK в условном режиме и оператор UNLINK управляют помещением заявок в список пользователя: если список пуст, заявка в него не помещается, а направляется к оператору с меткой, указанной операндом С.
Операторы LINK и UNLINK предоставляют возможность пользователю формировать свои списки в динамике вне зависимости от списков задержки, которые автоматически управляются системой GPSS World. При применении операторов LINK и UNLINK операторы QUEUE/DEPART для сбора статистики об очереди не используются, так как почти все те же данные можно получить из статистики о списке пользователя.
UNLINK – вывод заявок из списка пользователя. Вывод заявок из списка пользователя. Для вывода одного или нескольких заявок из списка пользователя и помещения их обратно в список текущих событий служит оператор UNLINK (вывести из списка), имеющий следующий формат:
[имя] UNLINK X A,B,C,[D],[E],[F]
Операндом А указывается имя или номер списка пользователя. Операнд В – метка оператора, в который переходят выведенные из списка пользователя заявки.
Операндом С указывается число выводимых заявок или ключевое слово ALL (по умолчанию). Операнды D и Е вместе с условным оператором X определяют способ и условия вывода заявок из списка пользователя. Значения оператора X те же, что и в операторе TEST (см. ЛР№5). В случае, когда условный оператор X должен использоваться, но не указан, по умолчанию он принимает значение Е (равенство). Если операнды D и Е не используются, не указывается и условный оператор X. В этом случае заявки выводятся с начала списка, а количество выводимых заявок определяется обязательным операндом С.
Операнд D может быть: булевой переменной; номером параметра заявки; ключевым словом BACK. Если операнд D является булевой переменной, операнд Е и оператор X не используются. Булева переменная вычисляется относительно заявки, находящейся в списке пользователя. Если результат не равен нулю, т. е. условие вывода выполняется, заявка выводится. Количество выводимых заявок определяется операндом С. Однако выведено может быть и меньше, чем указано операндом С: по числу ненулевых результатов вычисления булевой переменной. Кроме того, и заявок в списке пользователя может быть меньше, чем указано операндом С. Если операндом D указано ключевое слово BACK, операнд Е и условный оператор X также не используются, а заявки выводятся с конца списка в количестве, определяемом обязательным операндом С. Если операнд D не булева переменная и не ключевое слово BACK, должны быть указаны операнд Е и условный оператор X. Операнд 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 выводящей заявки, и направляет в оператор с меткой Арр1 все заявки, содержимое параметра Арр2 которых равно содержимому одноименного параметра выводящей заявки. Если таких параметров в списке не окажется, то выводящая заявка будет направлена в оператор с меткой АррЗ, в противном случае – к следующему оператору.
Отметим следующие особенности выполнения оператора UNLINK. Во-первых, если операнды D и Е содержат ссылки на СЧА заявок, операнд D вычисляется относительно заявок в списке пользователя, а операнд Е – относительно активной заявки. Во-вторых, после вывода заявок из списка планировщик продолжает или начинает продвижение заявки с наивысшим приоритетом, а при равенстве приоритетов отдает предпочтение заявке-инициатору вывода.
Рассмотрим примеры использования списков пользователя для организации сложных дисциплин обслуживания. Пусть в одноканальной СМО с ожиданием требуется организовать дисциплину обслуживания, при которой приоритет отдается заявкам с наименьшим временем обслуживания. Реализация такой модели приведена в примере 4.
Пример 4
GENERATE (Exponential(23,0,200)) ; Источник заявок
ASSIGN Nbl,(Exponential(34,0,120)) ; Записать в параметр время
;обслуживания
GATE NU Evm.Otst ; ОУ свободно?
Арр1 SEIZE Evm ; Занять ОУ
ADVANCE P$Nbl ; Обслуживание
RELEASE Evm ; Освободить ОУ
UNLINK Pol,Арр1,1 ; Вывести из списка пользователя
TERMINATE ; Выход обслуженных заявок из СМО
Otst LINK Pol, P$Nbl ; Список пользователя
GENERATE 3600 ; Время моделирования
TERMINATE 1
В параметр с именем Nbl поступающих в модель заявок в операторе ASSIGN записывается случайное время обслуживания, вычисляемое с использованием встроенного генератора экспоненциального распределения. Если ОУ Evm свободно, то оператор GATE впускает заявку в оператор SEIZE, и ОУ занимается на время P$Nbl. Если же в момент поступления заявки ОУ занято, то оператор GATE перенаправляет заявку в оператор LINK с меткой Otst, который вводит ее в список пользователя Pol, упорядочивая заявки по возрастанию времени обслуживания, записанного в параметре P$Nbl. Оператор UNLINK по освобождении ОУ выводит с начала списка заявку с наименьшим временем обслуживания, обеспечивая тем самым заданную дисциплину.
Пусть в одноканальной СМО с ожиданием требуется организовать дисциплину обслуживания, при которой заявки не обслуживаются, если они находятся в очереди более Vrem единиц модельного времени. Реализация такой модели показана в примере 5.
Пример 5
Vrem EQU 250 ; Время ожидания в очереди
Preb BVARIABLE (AC1-P1) 'LE' Vrem ; Определение булевой переменной
GENERATE (Exponential(23,0,120)) ; Источник заявок
ASSIGN Nbl,(Exponential(34,'0,'150)) ; Записать в параметр
GATE NU Evm,Otst ; ОУ свободно?
Арр1 SEIZE Evm ; Занять ОУ
ADVANCE P$Nb ; Обслуживание
RELEASE Evm ; Освободить ОУ
UNLINK Pol,App1,1,BV$Preb, ,Term2 ; Вывести из списка
Term1 TERMINATE ; Обслуженные заявки
Term2 TERMINATE ; Потерянные заявки
Otst ASSIGN 1,AC1 ; Записать в параметр абсолютное
; модельное время
LINK Pol,P1 ; Список пользователя
GENERATE 3600 ; Время моделирования
TERMINATE 1
В параметр Nbl поступающих в модель заявок в операторе ASSIGN записывается случайное время обслуживания. В список пользователя с именем Pol заявки помещаются также, как в предыдущем примере. Перед оператором LINK вставлен оператор ASSIGN с меткой Otst, который в первый параметр заявки Р1 записывает абсолютное модельное время в момент помещения ее в список пользователя.
В качестве операнда D оператора UNLINK используется булева переменная Preb, в которой сравнивается время пребывания заявки в очереди с заданным ограничением Vrem. Время нахождения в очереди определяется как разность между абсолютным модельным временем в момент входа выводящей заявки в оператор UNLINK и абсолютным модельным временем помещения заявки в список пользователя, хранящимся в параметре Р1. При входе выводящей заявки булева переменная вычисляется относительно заявки, находящейся в списке пользователя. Если результат вычисления не нулевой, т. е. заданное в.булевой переменной условие выполняется, выводится одна заявка, так как операнд С равен 1.
По количеству заявок, вошедших в оператор TERMINATE с меткой Met2, можно увидеть в скольких случаях в списке пользователя не оказалось заявок, время обслуживания которых было меньше или равно заданному ограничению пребывания в очереди.