Выбор объектов, удовлетворяющих заданному условию.
Для определения количества объектов (из заданного множества объектов), удовлетворяющих заданному условию, используется блок COUNT. Номер первого из таких объектов может быть найден с помощью блока SELECT.
Блок COUNT относится к блокам с расширенным полем операции и имеет вид:
< COUNT XXX A, B, C, D, E >
Здесь в полях операндов задается следующая информация:
А — номер параметра с указанием формата (PF, РН, РВ), используемого для организации счетчика числа объектов;
В, С — соответственно, нижняя и верхняя границы диапазона изменения номеров объектов, для которых проверяется заданное условие;
D — СЧА, значение которого сравнивается со значением СЧА объекта, указанного в поле Е;
Е — СЧА анализируемых объектов из табл. П.5
Расширение поля операций может быть двух типов:
1) XXX — мнемонические обозначения логических условных операторов, приведенных для различных типов объектов в П.6. В этом случае поля D, Е могут быть пустыми.
Пример.
COUNT SF 5PH, 10, 20
В результате работы данного оператора количество заполненных памятей из множества памятей с номерами от 10 до 20 будет занесено в пятый параметр формата "байт" транзакта.
2) XXX — указатель отношения L, LE, Е, NE, G, GE. При этом поля D и Е всегда должны быть заданы.
Пример.
COUNT LE 1PB, 1, 5, X10, FC
На множестве устройств с номерами 1-5 подсчитывается количество устройств, у которых счетчик числа входов (FC) меньше либо равен текущему значению ячейки 10 формата "слово". Полученное число записывается в параметр 1 формата "байт", вошедшего в блок транзакта.
Блок SELECT имеет вид:
< SELECT XXX A, B, C, D, E, F >
Назначение полей A, B, C, D, E аналогично блоку COUNT. Поле F используется для записи альтернативного адреса, если заданному условию не удовлетворяет ни один из объектов указанного множества.
Для записи расширенного поля операции наряду с вариантами 1, 2 может использоваться следующий вариант:
3) XXX — ключевые слова MIN или МАХ, соответствующие режимам поиска объекта с минимальным и максимальным значением указанного СЧА.
Работа со списками пользователя.
В каждый момент модельного времени транзакты, находящиеся в имитационной модели, заносятся управляющей программой (симулятором) в один из четырех основных типов списков:
— список текущих событий (например, транзакты, задержанные в блоках TRANSFER, TEST, GATE, а также при невозможности войти в блоки SEIZE, ENTER);
— список будущих событий (транзакты, находящиеся в блоках ADVANCE, GENERATE);
— список прерываний (транзакты, обслуживание которых прервано в результате прохождения блоков SEIZE и PREEMPT);
— список синхронизации (транзакты, находящиеся в блоках MATCH, ASSEMBLE).
Данные списки являются недоступными для пользователя в процессе функционирования имитационной модели. Содержимое списков может быть распечатано по завершении моделирования по особому запросу (через оператор START) или в случае обнаружения ошибки выполнения программы.
В GPSS/H имeeтcя еще один тип списков, доступных пользователю в процессе имитационного моделирования и называемых, вследствие этого, списками пользователя. Использование списков пользователя обычно преследует две цели:
1) сокращение затрат машинного времени при обработке очередей;
2) организация специальных дисциплин обслуживания (например: первым пришел — последним обслужился; по убыванию значений параметра транзакта).
Сокращение затрат машинного времени достигается за счет временного удаления транзактов, находящихся в очереди, из списков текущих событий и помещения их в списки пользователя. При этом транзакты оказываются во временно неактивном состоянии. При изменении модельного времени управляющая программа обращается только к первому транзакту в списке и продвигает его при необходимости по указанному адресу. Если же транзакты находятся в списке текущих событий, то тратится дополнительное машинное время на анализ возможности продвижения для всех транзактов в данном списке.
Для помещения транзактов в список пользователя используется блок LINK, имеющий вид:
< LINK A, B, C >
где поля операндов имеют следующее назначение:
А — номер (имя) списка пользователя;
В — режим упорядочивания списка пользователя (дисциплина обслуживания), возможны следующие записи:
— FIFO — вошедший транзакт помещается в конец списка ("первым пришел — первым обслужился");
— LIFO — вошедший транзакт помещается в начало списка ("последним пришел — первым обслужился");
— номер параметра — транзакты располагаются в списке по возрастанию значений указанного параметра (транзакт с минимальным значением параметра — первый в списке, а с максимальным — последний);
С — альтернативный адрес.
Применение поля С предусматривает использование индикатора списка пользователя ind, принимающего значения: 0 - если транзакт входит без задержки в блок, адрес которого указан в поле С, и на вход в данный блок не претендуют ранее поступившие транзакты; 1 — в противном случае. Заметим, что начальное значение индикатора равно нулю.
Для удаления транзактов из списка пользователя предназначен блок UNLINK. Упрощенный вариант этого блока может быть представлен в виде:
< UNLINK A, B, C >
А — номер (имя) списка пользователя;
В — номер (метка) блока, к которому переходят удаляемые транзакты;
С — число удаляемых транзактов (константа, СЧА или ключевое слово ALL, означающее удаление всех транзактов).
Работу блоков LINK и UNLINK поясним на примере.
Пример.
GENERATE 1000, FN1
QUEUE QUE1
LINK CHAIN, FIFO, CAN
CAN SEIZE FAC1
DEPART QUE1
ADVANCE 700, FN1
RELEASE FAC1
UNLINK CHAIN, CAN, 1 TERMINATE
Целью использования блоков LINK, UNLINK в приведенном примере является уменьшение затрат машинного времени. Опишем работу данных блоков. Так как блок LINK имеет альтернативный адрес, то при вхождении в него транзакта проверяется состояние индикатора списка CHAIN. Если ind = 0 (например, для первого транзакта), то транзакт направляется по альтернативному адресу (к устройству FAC 1) и полагается: ind = 1. Если ind = 1, то транзакт, входящий в блок LINK, заносится в конец списка пользователя CHAIN, поскольку указан режим FIFO. Если при входе транзакта в блок UNLINK список пользователя не пуст, то один (первый) транзакт из списка CHAIN удаляется и направляется к блоку с меткой CAN. Индикатор списка остается равным 1, так как устройство FAC1 вновь занято. Если же в момент входа транзакта в блок UNLINK список CHAIN пуст, то полагается ind = 0.
Экономия машинного времени достигается за счет того, что управляющая программа не просматривает все транзакты, ожидающие обслуживания на устройстве FAC1, а без дополнительных проверок направляет на обслуживание первый транзакт в списке CHAIN.