Este documento oferece aos profissionais e consumidores de simulação uma base sobre como funciona o software de simulação de eventos discretos. Os tópicos incluem sistemas de eventos discretos; entidades, recursos, elementos de controle e operações; execuções de simulação; estados de entidades; listas de entidades; e seu gerenciamento. São descritas as implementações dessas ideias genéricas no AutoMod, SLX, ExtendSim e Simio. O artigo conclui com vários exemplos de "por que é importante" que os modeladores saibam como seu software de simulação funciona, incluindo discussões sobre AutoMod, SLX, ExtendSim, Simio, Arena, ProModel e GPSS/H.
Uma abordagem de "caixa preta" é frequentemente adotada no ensino de software de simulação de eventos discretos. As características externas do software são estudadas, mas a base sobre a qual o software se apóia é abordada apenas brevemente ou totalmente ignorada (por falta de tempo). As escolhas feitas na implementação da base e o impacto dessas escolhas na execução do modelo passo a passo podem não ser estudados. O modelador pode, então, não ser capaz de pensar bem quando se depara com o desenvolvimento de boas abordagens para modelar situações complexas, usando ferramentas interativas para entender as condições de erro que surgem durante o desenvolvimento do modelo e usando ferramentas interativas para verificar se a lógica complexa do sistema foi modelada corretamente. O objetivo aqui, portanto, é descrever os fundamentos lógicos da simulação de eventos discretos e ilustrar esse material em termos de várias implementações de software de simulação de eventos discretos.
Nas Seções 2, 3 e 4, comentamos sobre a natureza da simulação de eventos discretos; construções básicas de simulação, como entidades, recursos, elementos de controle e operações; e execução de modelos. A Seção 5 discute quatro implementações específicas de regras de gerenciamento de entidades. Por fim, a Seção 6 explora vários aspectos de "por que é importante". Ao longo deste documento, os termos que definimos estão em negrito na primeira utilização. Os termos específicos de ferramentas são escritos em maiúsculas ou, quando apropriado, em MAIÚSCULAS.
Este documento é uma versão revisada de um documento semelhante que foi publicado inicialmente nos Anais da Conferência de Simulação de Inverno de 1996 (Schriber e Brunner 1996). Uma versão do artigo de 1996 tem sido apresentada na conferência todos os anos desde 1996, com atualizações ocasionais, como a modificação do conjunto de linguagens abordadas em detalhes. Por exemplo, o documento de 1996 abordou as regras de gerenciamento de listas de entidades e "por que isso é importante" para SIMAN (Arena), ProModel e GPSS/H. (Uma versão substancialmente ampliada do documento de 1996, contendo figuras, fluxogramas e explicações adicionais, pode ser encontrada em Schriber e Brunner (1998)).
A "visão de mundo do fluxo de transações" geralmente fornece a base para a simulação de eventos discretos. Nessa visão de mundo, um sistema é visualizado como consistindo de unidades discretas de tráfego que se movem (fluem) de um ponto a outro do sistema enquanto competem entre si pelo uso de recursos escassos (com restrição de capacidade). As unidades de tráfego às vezes são chamadas de "transações", dando origem à expressão "fluxo de transações". Diversos sistemas se encaixam na descrição anterior. Entre eles estão os sistemas de fabricação, manuseio de materiais, serviços, assistência médica, comunicação e processamento de informações, bem como outros sistemas gerais de filas.
Fundamentalmente, uma simulação de evento discreto é aquela em que o estado de um modelo muda apenas em um conjunto discreto, mas possivelmente aleatório, de pontos de tempo simulados, chamados de tempos de evento. Duas ou mais unidades de tráfego geralmente precisam ser manipuladas em um mesmo ponto de tempo. Esse movimento "simultâneo" do tráfego é obtido manipulando-se as unidades de tráfego em série nesse momento. Isso gera complexidades lógicas porque levanta questões sobre a ordem específica em tempo real em que duas ou mais unidades de tráfego devem ser processadas em um determinado momento simulado.
Os desafios enfrentados por um modelador aumentam para o projetista de uma linguagem de modelagem. O projetista deve levar em conta os requisitos lógicos da simulação de eventos discretos de forma generalizada. Existem escolhas e compensações. Como resultado, embora as linguagens de simulação de eventos discretos sejam semelhantes em termos gerais, elas podem diferir em particularidades sutis, mas importantes. Procuramos expandir essa noção e fornecer exemplos específicos neste documento. Antes de fazermos isso, porém, as seções a seguir apresentam outros conceitos gerais de simulação.
O termo entidade é usado aqui para designar uma unidade de tráfego (uma "transação") em um modelo. As entidades instigam e respondem a eventos. Um evento é um acontecimento instantâneo que altera o estado de um modelo (ou sistema). Em um modelo de um sistema de preenchimento de pedidos, por exemplo, a chegada de um pedido (um evento) pode ser simulada trazendo uma entidade para o modelo. Há dois tipos possíveis de entidades, aqui denominadas entidades externas e entidades internas. As entidades externas são aquelas cuja criação e movimentação são explicitamente organizadas pelo modelador (exemplo: chegada de um pedido em um ponto de processamento de pedidos). Por outro lado, as entidades internas são criadas e manipuladas implicitamente pelo software de simulação. Por exemplo, as entidades internas podem ser usadas em algumas linguagens para acionar falhas simuladas de máquinas e implementar programações de máquinas, enquanto as entidades externas podem ser usadas para simular o uso de máquinas para o processamento de peças.
O termo recurso designa um elemento do sistema que fornece serviço (como uma furadeira, um veículo guiado automaticamente, um trabalhador ou espaço em um buffer de entrada). As entidades normalmente usam recursos (por exemplo, uma entidade de trabalho em processo reivindica espaço em um buffer de entrada e, em seguida, captura um veículo guiado automaticamente para mover a entidade para o buffer de entrada). Os recursos geralmente têm capacidade limitada, portanto, as entidades competem por seu uso e, às vezes, precisam esperar para usá-los, sofrendo atrasos como resultado (fila). O termo elemento de controle designa uma construção que suporta outros tipos de atraso ou alternativas lógicas com base no estado de um sistema. Os elementos de controle podem assumir a forma de interruptores, contadores, valores de dados do usuário e valores de dados do sistema incorporados à ferramenta de modelagem. Condições complexas podem ser avaliadas com expressões aritméticas e/ou booleanas que examinam o estado dos elementos de controle relevantes.
Uma operação é uma etapa (ou uma série de etapas) executada por ou em uma entidade enquanto ela se move em um sistema. As operações aplicáveis a um navio em um porto podem incluir: chegar ao porto; solicitar um atracadouro; capturar um atracadouro; solicitar um rebocador; capturar um rebocador; ser puxado para o atracadouro; liberar o rebocador; carregar carga; solicitar um rebocador; ser puxado para fora do atracadouro; liberar o atracadouro; ser puxado para águas abertas; liberar o rebocador; partir.
Um projeto de simulação envolve a execução de experimentos. Os experimentos são diferenciados pelo uso de alternativas na lógica e/ou nos dados de entrada de um modelo. Por exemplo, regras alternativas de sequenciamento de peças e/ou variação do número de vários tipos de máquinas (recursos) podem ser experimentadas no modelo de um sistema de produção. Da mesma forma, o número de berços de carga e descarga em um porto pode ser variado para avaliar o impacto no desempenho do sistema. Cada experimento consiste em uma ou mais replicações (tentativas). Uma replicação é uma simulação que usa a lógica e os dados do modelo do experimento, mas seu próprio conjunto exclusivo de números aleatórios e, portanto, produz resultados estatísticos exclusivos que podem ser analisados como parte de um conjunto de tais replicações (todas independentes). Uma replicação consiste em inicializar o modelo, executá-lo até que uma condição de término de execução seja atendida e relatar os resultados. Essa fase de "execução" é chamada de execução.
Durante uma execução, o relógio da simulação (um valor de dados armazenado e gerenciado internamente) rastreia a passagem do tempo simulado. O relógio avança (automaticamente) em etapas discretas (normalmente de tamanho desigual) durante a execução. Após todas as ações possíveis terem sido executadas em um determinado momento simulado, o relógio é avançado até o momento do próximo evento mais antigo. Em seguida, as ações apropriadas são executadas nesse novo tempo simulado etc. Essencialmente, a execução de uma execução assume a forma de um loop de duas fases: "executar todas as ações possíveis no tempo simulado atual" e, em seguida, "avançar o relógio", com essas duas fases repetidas várias vezes até que uma condição de término de execução (geralmente um tempo simulado especificado pelo modelador, o número de entidades processadas ou alguma outra condição) ocorra. Essas duas fases são chamadas respectivamente de fase de movimentação da entidade (EMP) e fase de atualização do relógio (CUP).
À medida que a simulação é executada, as entidades migram de um estado para outro enquanto se movem por um modelo. Os cinco estados normalmente usados são:
Ativo - O estado da entidade que está se movendo no momento é o estado ativo. Por "entidade em movimento no momento" queremos dizer a entidade que está executando a lógica de decisão no modelo. Apenas uma entidade se move em qualquer instante do tempo do relógio de parede. Essa entidade se move até encontrar um atraso de um tipo ou outro. Em seguida, ela migra para um estado alternativo.
Pronto - Durante uma fase de movimentação de entidade, pode haver mais de uma entidade pronta para se movimentar, mas as entidades só podem se movimentar (estar no estado ativo) uma a uma. O estado pronto é o estado das entidades que estão esperando para entrar no estado ativo durante a fase de movimentação da entidade atual.
Atraso no tempo- O estado de atraso no tempo é o estado das entidades que aguardam que um tempo simulado futuro conhecido seja alcançado para que elas possam (re)entrar no estado pronto. Uma entidade "parte" está em um estado com atraso de tempo, por exemplo, enquanto aguarda o tempo simulado futuro no qual uma operação que está sendo executada nela terminará.
Condição atrasada - O estado de condição atrasada é o estado de entidades atrasadas até que alguma condição especificada ocorra, por exemplo, uma entidade "parte" pode esperar no estado de condição atrasada até que chegue sua vez de usar uma máquina. As entidades com atraso de condição são transferidas automaticamente do estado com atraso de condição para o estado pronto quando as condições especificadas permitirem.
Dormente - Às vezes, é desejável ou necessário colocar as entidades em um estado do qual nenhuma saída será acionada automaticamente por alterações nas condições do modelo. Chamamos esse estado de estado dormente. As entidades em estado dormente dependem da lógica fornecida pelo modelador para transferi-las do estado dormente para o estado pronto. As entidades de job-ticket podem ser colocadas em um estado inativo, por exemplo, até que uma entidade operadora decida qual job-ticket puxar em seguida, com a consequente transferência da entidade de job-ticket para o estado pronto. Nesse caso, as condições específicas em vigor ao selecionar o tíquete de trabalho podem não ser conhecidas até que chegue o momento de a entidade operadora selecionar um tíquete de trabalho.
Em nosso modelo genérico, gerenciamos as entidades designando uma Entidade Ativa e várias listas de entidades. A entidade ativa (a entidade de estado ativo) se move sem parar até encontrar uma etapa (tentada) que a faça migrar para outro estado de entidade (transfira-a para outra lista) ou a remova do modelo. Uma entidade em estado pronto torna-se, então, a próxima entidade em estado ativo. Eventualmente, não há mais entidades em estado pronto no momento atual. O EMP então termina e um CUP começa. As listas a seguir são usadas para organizar as entidades. (A dinâmica do movimento da entidade entre essas listas será ilustrada em uma sequência de slides do PowerPoint durante a palestra da Conferência de Simulação de Inverno a ser dada em conexão com este tutorial).
Lista de eventos atuais - As entidades no estado pronto são mantidas em uma única lista que chamamos de lista de eventos atuais (CEL). As entidades migram para a CEL a partir da lista de eventos futuros, listas de atrasos e listas gerenciadas pelo usuário (cada uma descrita abaixo). Além disso, as entidades clonadas da entidade de estado ativo geralmente começam sua existência na CEL. As entidades CEL são geralmente classificadas na ordem FIFO (primeiro a entrar, primeiro a sair). Algumas ferramentas de software fornecem um atributo Prioridade de entidade incorporado usado para ordenar as entidades na CEL por prioridade (com empates resolvidos usando FIFO).
Lista de eventos futuros - As entidades no estado com atraso de tempo pertencem a uma única lista na qual são inseridas no início de seu atraso baseado em tempo. Essa lista, chamada aqui de lista de eventos futuros (FEL), geralmente é classificada pelo aumento do tempo de movimentação da entidade. O tempo de movimentação é o tempo simulado no qual uma entidade está programada para tentar se movimentar novamente (o fim do tempo de tratamento de um paciente em uma clínica ou o fim do tempo de processamento de uma peça em um sistema de fabricação, por exemplo). No momento da inserção da entidade no FEL, o tempo de movimentação da entidade é calculado adicionando-se o valor do relógio de simulação à duração conhecida (amostrada) do atraso baseado em tempo. Após o término de um EMP, a CUP define (avança) o valor do relógio para o tempo de movimentação da entidade mais bem classificada (menor tempo de movimentação) do FEL. Essa entidade é então transferida do FEL para o CEL, migrando do estado de atraso de tempo para o estado pronto e preparando o cenário para o início do próximo EMP. A declaração anterior pressupõe que não há outras entidades no FEL cujo tempo de deslocamento corresponda ao valor atualizado do relógio. No caso de vínculos de tempo de movimentação, algumas ferramentas transferirão todas as entidades com vínculo de tempo do FEL para o CEL durante um único CUP, enquanto outras ferramentas adotam uma abordagem de "apenas uma transferência de entidade por CUP". As linguagens que fornecem entidades internas geralmente usam o FEL para dar suporte aos requisitos de tempo dessas entidades. (O FEL inclui entidades internas e externas).
Listas deatraso - As listas (podem ser muitas) de entidades no estado de atraso de condição são chamadas de listas de atraso. Essas entidades estão aguardando (por exemplo, aguardando sua vez de usar uma máquina) até que seu atraso seja resolvido para que possam ser transferidas automaticamente para o estado pronto no CEL. As listas de atrasos, que geralmente são criadas automaticamente pelo software de simulação, são gerenciadas usando um dos dois tipos de espera. Se um atraso puder ser relacionado facilmente aos eventos do modelo que podem resolver o atraso, então a espera relacionada poderá ser usada para gerenciar a lista de atrasos. Por exemplo, suponha que o status de uma máquina mude de ocupado para ocioso. Em resposta, o software pode remover automaticamente a próxima entidade em espera da lista de atrasos apropriada e colocá-la no estado pronto no CEL. A espera relacionada é a abordagem predominante usada para gerenciar atrasos condicionais. Se a condição de atraso for muito complexa para ser facilmente relacionada a eventos que possam resolvê-la, pode-se usar a espera sondada. Com a espera sondada, o software verifica rotineiramente se as entidades podem ser transferidas de uma ou mais listas de atrasos para o estado pronto. As condições de atraso complexas para as quais a espera sondada pode ser útil incluem combinações booleanas de alterações de estado, por exemplo, um berço está vazio e um rebocador está ocioso.
Listas gerenciadas pelo usuário As listas(podem ser muitas) de entidades no estado inativo são chamadas de listas gerenciadas pelo usuário. O modelador deve tomar medidas para estabelecer essas listas e, normalmente, deve fornecer a lógica necessária para transferir entidades de e para as listas. Exceto por pontos de serviço muito simples de uma linha e um servidor em um sistema, o software subjacente não tem como saber por que as entidades foram colocadas em listas gerenciadas pelo usuário e, portanto, não tem base para remover automaticamente as entidades dessas listas.
As ferramentas escolhidas aqui para comentar as particularidades da implementação são AutoMod (Phillips 1997); SLX (Henriksen 2000; Schulze 2008); ExtendSim (Imagine That Incorporated 2015; Krahl 2012); e Simio (Kelton et al., 2014). Uma versão anterior deste artigo (Schriber e Brunner 1996) abordou o SIMAN (Arena) (Kelton et al., 2014), o ProModel (ProModel Corporation 2015) e o GPSS/H (Henriksen e Crain 2000) com detalhes semelhantes. Acreditamos que essas ferramentas são representativas, mas claramente não são exaustivas (consulte Swain 2015 para uma pesquisa bienal das muitas ferramentas disponíveis).
A lista de eventos atuais é chamada de Current Event List (CEL) no AutoMod (consulte a Tabela 1). Cargas clonadas, cargas que saem da FEL devido a uma atualização do relógio e cargas ordenadas nas listas de pedidos são colocadas imediatamente na CEL. A regra de inserção é classificar primeiro por prioridade (a prioridade é um atributo incorporado de cada carga) e, em seguida, FIFO dentro da prioridade. Quando a CEL fica vazia, a Condition Delay List (lista de atrasos de condição) (veja abaixo) é verificada e as cargas podem ser transferidas dessa lista para a CEL. Isso continua até que a CEL esteja vazia e não seja possível transferir mais cargas, momento em que o EMP termina e um CUP é iniciado.
A Lista de Eventos Futuros (FEL) do AutoMod é como as listas de eventos futuros em outras ferramentas. As cargas chegam à FEL no estado de atraso de tempo executando uma instrução WAIT FOR. O AutoMod permite a especificação de unidades de tempo (dia, hora, minuto, segundo) em uma instrução WAIT FOR. O AutoMod CUP remove vários Loads do FEL se eles estiverem empatados no primeiro tempo de movimentação, inserindo-os um a um em seu lugar apropriado no CEL. Há também entidades internas no AutoMod, chamadas de Logical Loads, que fazem coisas como esperar no FEL para acionar pausas de turnos programadas.
As listas de atrasos (DLs) são listas de cargas que aguardam para reivindicar a capacidade fornecida por qualquer um dos cinco elementos de capacidade finita (recurso, fila, bloco, contador ou limite de tráfego de processo; consulte a Tabela 1). Cada elemento de capacidade finita dentro do modelo tem um DL associado a ele. A espera que resulta nesses cinco casos é a espera relacionada. Sempre que a capacidade é liberada, uma carga do cabeçalho do DL do elemento é provisoriamente colocada no CEL (mas um espaço reservado é deixado no DL). Quando essa carga é encontrada durante o EMP, ela tenta reivindicar a capacidade solicitada. Se falhar (por exemplo, porque deseja duas unidades, mas somente uma está livre), ela retornará ao DL em seu lugar original (esse é o comportamento padrão que o modelador pode substituir. Consulte a Seção 6.2 para obter uma discussão mais geral). Imediatamente após essa avaliação, se ainda houver capacidade não utilizada, a próxima carga (se houver) no DL relevante é colocada no CEL. O processamento da carga ativa continua, seguido pela avaliação da próxima carga provisoriamente colocada. E assim por diante, provisoriamente, para cada carga seguinte (se houver) durante o EMP.
Para a espera condicional, além dos cinco casos descritos acima, o AutoMod tem uma instrução WAIT UNTIL que resulta em uma espera sondada. As condições WAIT UNTIL podem ser combinadas usando operadores booleanos. Se uma carga executar um WAIT UNTIL e a condição for falsa, a carga será colocada em uma única lista global do AutoMod chamada de CDL (Condition Delay List). Depois que a CEL for esvaziada, mas antes que o relógio da simulação seja atualizado, todas as cargas na CDL serão movidas para a CEL (na verdade, a CDL "se torna" a CEL) se houver uma alteração de estado em pelo menos um elemento do mesmo tipo geral (por exemplo, fila) para o qual qualquer carga na CDL esteja aguardando (esse mecanismo é principalmente "sondado", em que o processo de sondagem é acionado por uma alteração no estado de pelo menos um elemento do mesmo tipo geral).
Se o CEL agora não estiver vazio, o EMP será retomado. Se a condição pela qual uma carga do CEL está esperando ainda não foi atendida, o AutoMod move essa carga do CEL de volta para o CDL. Em alguns casos, o CDL pode ser esvaziado várias vezes durante um EMP até que o CEL seja esvaziado sem ter acionado uma alteração de estado relacionada a qualquer carga no CDL. Ocorre então um CUP. Devido ao potencial de migração repetitiva de listas com WAIT UNTIL, o fornecedor do AutoMod incentiva o uso de listas de pedidos ou outros mecanismos de controle explícito para gerenciar esperas complexas.
O AutoMod implementa o estado inativo com listas de pedidos, que são listas de cargas gerenciadas pelo usuário. Depois que uma Carga se coloca em uma Lista de Pedidos (executando uma Ação ESPERAR PARA SER PEDIDO), ela só pode ser removida por outra Carga (ou outro elemento ativo do modelo, como um Veículo) que execute uma Ação de PEDIDO. Uma Ação de PEDIDO pode especificar uma quantidade de Cargas ou uma condição que deve ser satisfeita para uma determinada Carga para que essa Carga seja pedida, ou ambas. As Cargas encomendadas com sucesso são colocadas imediatamente na CEL (uma de cada vez, de acordo com a forma como foram escolhidas na Lista de Pedidos e classificadas na CEL por prioridade, com os empates de prioridade resolvidos FIFO). As Listas de Pedidos podem obter melhorias de desempenho em relação à espera CDL porque as Listas de Pedidos nunca são escaneadas, exceto por solicitação explícita. As Listas de Pedidos do AutoMod oferecem vários recursos interessantes, incluindo: a possibilidade de uma Carga de pedido fazer um pedido de retorno se a quantidade do PEDIDO não for atendida; a possibilidade de uma Carga em uma Lista de Pedidos ser ordenada a continuar na próxima Ação em vez de em um Processo (esse recurso é útil para o controle de handshaking); e a possibilidade de ter uma função chamada para cada Carga na Lista de Pedidos (usando a Ação PEDIDO...SATISFATÓRIO).
O AutoMod tem várias construções de manuseio de materiais que são integradas à movimentação de cargas. Para sistemas de veículos, há três outros tipos de listas (não incluídos na Tabela 1). As cargas nas Listas de Carga Pronta (LRL) (uma lista por sistema de veículo) estão esperando para serem coletadas por um veículo. As cargas reivindicadas (mas ainda não coletadas) por um veículo residem na Vehicle Claim List (VCL) do veículo. As cargas reivindicadas que foram coletadas residem na Vehicle Onboard List (VOL) do veículo. O veículo então se torna a "carga" ativa e se move entre as listas do AutoMod (FEL, CEL e possivelmente DL) em vez das próprias cargas.
A SLX é uma linguagem hierárquica na qual os primitivos incorporados estão em um nível mais baixo do que a maioria das outras linguagens de simulação, facilitando a definição do comportamento de muitos elementos do sistema pelo usuário (ou desenvolvedor). Essa filosofia de design permite que o usuário (ou desenvolvedor) da SLX crie ferramentas de modelagem de nível superior cujos construtos tenham um comportamento modificável definido com precisão. Os equivalentes dos termos genéricos para usuários de SLX de baixo nível são apresentados na Tabela 2. Por exemplo, o SLX usa Variáveis de Controle para atuar como Elementos de Controle. O modificador "controle" pode ser anexado a uma variável de qualquer tipo de dados (inteiro, real, string etc.). Uma variável de controle pode ser global ou pode ser uma variável local declarada na definição de classe de um objeto. (Uma variável declarada na classe é um atributo em outras ferramentas).
O SLX tem dois tipos de Objetos: Ativo e Passivo. Os dois se distinguem pela presença de ações - declarações executáveis - na definição da classe de um objeto ativo (mesmo sem ações, os objetos passivos são úteis por si só, funcionando como estruturas de dados complexas definidas pelo usuário). A Tabela 3 mostra como as ferramentas de nível superior baseadas em SLX podem explorar os recursos de definição do SLX.
A lista de eventos atuais é chamada de Current Events Chain (CEC) no SLX. Os membros da CEC recebem o interessante nome de Puck. O que é um Puck? O SLX dissocia o conceito de um Objeto Ativo (com seus dados locais associados) de um Puck, que é a "entidade móvel" que executa as ações, carrega seus próprios dados de agendamento de entidade e migra de uma lista para outra. O efeito dessa dissociação é que um único objeto pode "possuir" mais de um Puck. Todos os Pucks pertencentes a um único objeto compartilham os dados locais do objeto (atributos). Por exemplo, uma aplicação desse recurso de "paralelismo local" (em comparação com o "paralelismo global" oferecido pelas ações de "clonagem" ou "divisão" em outras linguagens) é o uso de um segundo Puck para simular um tempo de balk enquanto o Puck original está aguardando alguma condição. (Se a condição ocorrer antes do término do tempo de espera, não haverá espera; caso contrário, haverá espera).
A ativação de um novo objeto cria um Puck e o coloca em ação. Em muitos casos, nenhum Puck adicional é criado para esse Objeto, e a combinação de um Objeto ativo e seu Puck forma o equivalente a uma entidade (os Objetos passivos não têm ações e, portanto, não possuem Pucks). Os Pucks recém-ativados, os Pucks que saem do FEC devido a uma atualização do relógio e os Pucks reativados (veja abaixo) são colocados no CEC, classificados FIFO por prioridade. A CEC fica vazia quando um PEM termina.
A Cadeia de Eventos Futuros (FEC) do SLX é como as listas de eventos futuros em outras ferramentas. Os pucks chegam à FEC no estado com atraso de tempo executando uma instrução ADVANCE. O SLX CUP removerá vários Pucks da FEC se eles estiverem empatados para o primeiro tempo de movimentação, inserindo-os um a um em seu lugar apropriado na CEC. Como a funcionalidade do kernel do SLX não inclui tempos de inatividade ou mesmo a geração repetitiva de Pucks (chegadas programadas), toda a atividade no SLX FEC se desdobra conforme especificado pelo desenvolvedor do modelo SLX. De modo mais geral, se um usuário estiver usando um modelo (ou usando um construtor de modelos) que contenha primitivos de nível superior definidos por um desenvolvedor, é provável que todos os tipos de coisas estejam acontecendo nos bastidores, ocultos da visão do usuário de nível superior. As Listas de Atraso (DLs) no SLX são listas de Pucks que aguardam (via WAIT UNTIL) por mudanças de estado em qualquer combinação de Variáveis de Controle e o valor do relógio de simulação. Um Puck que aguarda uma condição composta envolvendo duas ou mais Variáveis de Controle é listado em mais de uma DL. Todas as construções de nível superior definidas pelos desenvolvedores podem usar esse mecanismo. Cada Variável de Controle (que pode ser uma Variável local, caso em que há uma para cada Objeto na Classe) tem uma DL separada associada a ela.
Uma DL é classificada por ordem de inserção. Todos os pucks em um DL são removidos sempre que a variável de controle associada muda de valor e são inseridos um de cada vez no CEC. Os Pucks removidos que estão aguardando condições compostas também são removidos provisoriamente de cada uma das outras Listas de Atraso às quais pertencem. À medida que esses Pucks são encontrados na CEC durante o EMP, aqueles que não passam no WAIT UNTIL são devolvidos à(s) Lista(s) de Atraso para as Variáveis de Controle que ainda contribuem para a falsidade da condição. Para as condições que incluem uma referência de relógio, o Puck é inserido, se necessário, na FEC, sujeito à remoção antecipada da FEC se a condição se tornar verdadeira devido a outras alterações na Variável de Controle. Esse mecanismo de espera relacionado de baixo nível baseado em Variáveis de Controle é a abordagem padrão do SLX para modelar todos os tipos de estados atrasados de condições simples ou compostas.
O SLX lida com o estado dormente de uma maneira única. Em vez de mover o Puck do estado ativo para uma lista gerenciada pelo usuário e suspendê-lo, tudo na mesma operação, o SLX divide essa operação em duas partes. Primeiro, o Puck geralmente se junta a um Conjunto. Mas o fato de entrar em um Conjunto não suspende automaticamente o Puck. Um Puck pode pertencer a qualquer número de Conjuntos. A associação ao conjunto apenas fornece a qualquer outro Puck acesso aos Pucks membros. Para entrar no estado inativo, um Puck executa uma instrução WAIT. Em seguida, ele é suspenso indefinidamente, fora de qualquer lista específica, até que outro Puck identifique o Puck em espera e execute uma instrução REACTIVATE para ele. Muitas vezes, esse outro Puck está examinando um Conjunto para encontrar o Puck a ser REATIVADO, mas um Conjunto não é exatamente o mesmo que uma lista gerenciada pelo usuário em nossa terminologia. Um Puck em estado inativo pode ser um membro de nenhum Conjunto (desde que um ponteiro para ele tenha sido armazenado em algum lugar) ou de um ou mais Conjuntos. Um desenvolvedor de SLX pode definir facilmente uma construção de lista gerenciada pelo usuário, usando Sets, WAIT e REACTIVATE como blocos de construção, que imita os de outras linguagens ou oferece seus próprios recursos exclusivos.
O ExtendSim (originalmente denominado Extend) usa uma arquitetura baseada em mensagens para simulação de eventos discretos. Vários tipos de mensagens são usados para programar eventos, impulsionar itens (entidades) em um modelo, impor a lógica incorporada em um modelo e forçar a computação. Os emissores e receptores de mensagens são blocos (operações), incluindo o bloco executivo (controlador mestre). No ExtendSim, é a execução do Bloco que é programada (quando um Bloco é executado, por exemplo, isso pode acionar o envio de mensagens para frente e para trás entre os Blocos, com o efeito de mover um Item ao longo de seu caminho baseado em Bloco em um modelo). A Tabela 4 resume os equivalentes do ExtendSim para os termos introduzidos na discussão genérica anterior.
Um Bloco é a construção básica de modelagem no ExtendSim. Cada bloco tem um ícone, conectores de passagem de mensagem, capacidade de diálogo e código de definição de comportamento. Os blocos de residência podem manter itens enquanto o tempo simulado passa, enquanto os blocos de passagem não podem (os itens passam pelos blocos de passagem em tempo simulado zero). Os modelos podem ser construídos selecionando-se blocos pré-programados das bibliotecas de blocos do ExtendSim. O modelador também pode modificar o código-fonte fornecido para os blocos da biblioteca (todos os blocos na versão básica do ExtendSim são de código aberto). Por fim, o modelador pode criar blocos personalizados a partir do zero (blocos programados pelo usuário) usando as ferramentas de desenvolvimento fornecidas pelo ExtendSim.
O ExtendSim usa uma matriz de tempo para programar futuras execuções de blocos. Para um determinado modelo, o Time Array contém um ou mais elementos para cada Bloco. Um elemento do Time Array registra o tempo futuro para o qual a execução desse Bloco foi programada. A possibilidade de um bloco ter mais de um elemento do Time Array é um aprimoramento da versão 7 da linguagem (a versão 8 é a atual). Esse recurso pode ser útil quando um bloco tem vários eventos diferentes, como, por exemplo, na modelagem de transportadores.
Os blocos que não estão programados para execução futura são temporariamente "apagados" com o registro de valores de tempo arbitrariamente grandes para eles no Time Array. Os blocos de residência que podem conter vários itens gerenciam internamente os tempos de eventos correspondentes, com apenas o primeiro dos tempos de eventos do bloco mantido no Time Array. Essa é uma lista de eventos de dois estágios, pois os blocos podem conter listas vinculadas otimizadas que funcionam como suas próprias listas de eventos futuros. A execução do bloco pode resultar no agendamento de futuras execuções do bloco. Por exemplo, se forem passadas mensagens que resultem na entrada de um Item em um Bloco de Residência de capacidade unitária projetado para manter o Item até que um determinado período de tempo simulado tenha decorrido, a entrada do Time Array para esse Bloco terá seu valor definido de acordo.
O número de blocos em um determinado modelo é constante, o que significa que a Matriz de Tempo tem um tamanho fixo e relativamente pequeno. Devido ao seu tamanho pequeno, o Time Array é pesquisado para encontrar a hora do evento iminente; ele não é mantido em ordem ordenada. Isso facilita a alteração da hora do evento por um bloco, pois não é necessário pesquisar a lista de eventos. O Next Times Array é usado para gerenciar a execução de blocos cuja execução foi programada por meio do Time Array. O Next Times Array é preenchido imediatamente antes da Fase de Execução de um Bloco (equivalente a um EMP no ExtendSim) da seguinte forma. Em cada CUP, o Time Array é pesquisado para encontrar o primeiro horário futuro em que a execução de um bloco foi programada. Os identificadores do Bloco correspondente (ou dos Blocos, no caso de empate de tempo) é (ou são) então colocado(s) no Next Times Array. A fase de execução do bloco (BEP) começa então, com o envio de mensagens pelo executivo ao bloco mais qualificado da matriz Next Times para iniciar sua execução.
A matriz Current Events é usada para gerenciar a retomada da execução de blocos cuja execução foi temporariamente suspensa durante a fase de execução de um bloco. Por exemplo, suponha que um bloco envie uma mensagem e o bloco receptor responda (devolva o controle) imediatamente ao bloco que a enviou (mesmo que o bloco receptor ainda tenha de fazer um processamento adicional no tempo simulado em questão). Nesse caso, o identificador do bloco receptor é adicionado à matriz de eventos atuais. Quando o Bloco remetente termina a execução, o Executivo envia uma mensagem ao Bloco mais qualificado no Current Events Array para retomar sua execução. Eventualmente, a matriz de eventos atuais fica vazia. Então, o executivo volta-se novamente para o Next Times Array, enviando uma mensagem para o bloco mais qualificado para iniciar a execução.
Durante uma fase de execução de bloco, os blocos podem se programar para serem executados no tempo simulado atual (ou seja, durante o BEP em andamento). A matriz de eventos atuais também entra em ação aqui para gerenciar a execução de blocos nesses casos. Por exemplo, se um bloco com restrição de capacidade se tornar incompleto como resultado da execução de algum outro bloco, o bloco incompleto colocará seu identificador no Current Events Array. Posteriormente (mas no mesmo tempo simulado), o executivo enviará uma mensagem ao bloco para iniciar a execução. O bloco tentará então puxar para si os itens (se houver) que estavam esperando para entrar no bloco (no ExtendSim, os itens podem ser puxados e empurrados por um modelo). Quando a Matriz de Eventos Atuais e a Matriz de Próximos Tempos ficarem vazias, a Fase de Execução do Bloco do ExtendSim será encerrada. Em seguida, o próximo CUP e BEP ocorrem, repetindo-se até que uma condição de término da simulação seja satisfeita. As listas de atraso consistem em itens atrasados em blocos de residência, aguardando sua vez de serem puxados ou empurrados para o(s) próximo(s) bloco(s). A passagem de mensagens é usada para realizar o puxar e empurrar quando as condições do modelo permitem. O ExtendSim fornece gerenciamento de espera relacionado a esses itens com base nas alternativas especificadas pelo usuário de primeiro a entrar, primeiro a sair (FIFO), último a entrar, primeiro a sair (LIFO), prioridade, atributo, renegação, correspondência e equação. A espera pela resolução de condições compostas é normalmente obtida no ExtendSim por meio da combinação adequada de blocos e da exploração da arquitetura baseada em mensagens do ExtendSim. Vemos isso como uma forma de espera relacionada, porque é uma mudança em um valor subjacente que aciona uma reavaliação da condição que provocou a espera em primeiro lugar.
Devido à arquitetura de mensagens do ExtendSim, a espera por sondagem geralmente não é necessária. Uma mensagem é enviada quando um valor é alterado e todas as condições são avaliadas nesse momento. A espera por um evento baseado em relógio pode ser obtida com o uso de um bloco que agenda eventos, por exemplo, Shift; Lookup Table; Equation. Esses blocos enviam uma mensagem em horários programados. Entretanto, a espera por sondagem está disponível com o uso do bloco Gate e a seleção da opção "Check demand at each event" (Verificar demanda a cada evento).
O modelador pode trabalhar com blocos programados pelo usuário para criar e gerenciar listas de seu próprio projeto. O código dos Blocos personalizados pode ser escrito para atingir os objetivos do modelador nesse sentido, assim como o código dos Blocos pré-programados do ExtendSim foi escrito para especificar o comportamento desses Blocos. O ExtendSim fornece funções que podem ser usadas pelos Blocos para compartilhar listas (arrays) com outros Blocos, dando suporte adicional ao gerenciamento de listas personalizadas nos modelos.
O Simio é uma linguagem orientada a objetos na qual todas as construções de modelos são objetos Simio derivados do mesmo objeto base. A maioria dos usuários do Simio usará principalmente objetos da Simio Standard Library para construir modelos. Entidades, recursos, servidores, estações de trabalho, fontes, sumidouros, nós e conectores são objetos comumente usados da biblioteca padrão. Por baixo, o Simio se baseia em processos que são compostos de etapas de processo individuais executadas por tokens. Os comportamentos dos objetos da Biblioteca Padrão são implementados (pelo designer do objeto) usando processos. Embora a maioria dos modelos seja criada usando esses objetos de alto nível, os usuários (e desenvolvedores) têm acesso total aos processos do Simio e podem desenvolver modelos completos, bem como objetos reutilizáveis, usando os processos do Simio. Além disso, os usuários podem aumentar o comportamento dos objetos existentes usando processos complementares e/ou subclasses de objetos existentes. Os próprios modelos do Simio são, na verdade, objetos que podem ser incorporados em outros modelos. A estrutura de objetos do Simio facilita o desenvolvimento de bibliotecas de objetos personalizadas que podem simplificar o processo de modelagem em diferentes domínios de aplicativos.
Os equivalentes dos termos genéricos para os usuários do Simio são apresentados na Tabela 5. Observe que qualquer objeto do Simio pode atuar como um recurso ao definir a propriedade "Resource Object" como True. O objeto Resource da Standard Library é análogo a um recurso no contexto deste documento. A relação entre os objetos de entidade do Simio e os tokens é semelhante em conceito à relação entre o objeto ativo e os pucks no SLX. Em particular, à medida que os objetos interagem (por exemplo, um objeto Entidade movendo-se por meio de um objeto Servidor para entrar na fila e acessar um recurso de capacidade finita), um ou mais tokens associados a esses objetos estão executando os processos (sequências de etapas) que compreendem o comportamento dos objetos. A capacidade de ter vários tokens executando processos diferentes em nome do mesmo objeto oferece flexibilidade de modelagem.
As propriedades e os estados do objeto servem como elementos de controle do Simio. As propriedades e os estados são atributos dos objetos. As propriedades são definidas no início de uma execução e não são alteradas durante a execução, enquanto os estados podem ser definidos e alterados a qualquer momento durante a execução do modelo. As propriedades são normalmente usadas durante a construção e a experimentação do modelo e os estados são normalmente usados durante a execução do modelo para controlar o fluxo e/ou rastrear e relatar estatísticas. Os eventos são um pouco mais abstratos no Simio do que em alguns outros pacotes. No Simio, os eventos são caracterizados por um tempo de execução (o tempo de simulação quando o evento ocorre), uma referência a uma chamada de procedimento (a ser executada quando o evento ocorre) e uma referência a um objeto (que fornece dados adicionais ao procedimento, quando necessário). O objeto referenciado de um evento pode ou não ser uma entidade visível para o usuário ou um token associado. Para eventos associados ao movimento da Entidade, o Objeto do evento refere-se a um Token associado à Entidade e o procedimento do evento executa uma etapa do processo (chamado de evento "token chegou a uma etapa"). A maioria dos eventos que ocorrem durante a execução de um modelo será desse tipo. Exemplos de outros eventos internos incluem eventos de fim de execução, eventos de estados que ultrapassam um limite, eventos de colisão de entidades etc. O Simio também oferece suporte a eventos definidos pelo usuário que podem ser disparados, aguardados e usados para acionar processos.
Durante a execução do modelo, quando ocorre a CUP e o Simio entra no EMP, todos os eventos programados para o tempo de simulação atual são removidos da pilha de eventos futuros (FEH) e colocados na lista de eventos atuais (CEL). A estrutura de dados do heap é usada para eventos futuros devido à sua eficiência computacional. O Simio executa todos os eventos na CEL (sequencialmente) antes de avançar o tempo de simulação para o próximo tempo de evento. Os eventos no CEL são priorizados pelo tipo de evento (normal, precoce e tardio). Os procedimentos de eventos podem criar outros eventos (eventos futuros, bem como eventos programados para o tempo de simulação atual), atualizar o estado do sistema, acionar o registro de estatísticas e encerrar a execução do modelo. As filas de alocação são listas de entidades que aguardam recursos. Quando um recurso se torna disponível, o Simio passa por um processo de realocação padrão em que a "primeira" entidade na fila de alocação (determinada pela regra de classificação da fila) será colocada na frente do CEL e a entidade que liberou o recurso será processada por etapas até atingir um atraso (um atraso de tempo, um atraso de condição ou um armazenamento especificado pelo usuário). Nesse processo, a última entidade liberadora é processada até atingir um atraso e a última entidade à qual foi alocada capacidade de recurso é a primeira a iniciar o processamento (no mesmo tempo de simulação). O Simio implementa o estado inativo usando elementos Storage ou Station. Um elemento Storage implementa uma fila lógica na qual os objetos podem ser "colocados" pelo usuário para remoção posterior. Os elementos Storage não têm localização física e um determinado objeto pode residir simultaneamente em vários Storages. Um elemento Station, por outro lado, define um local físico com restrição de capacidade onde os objetos de entidade podem ser armazenados para remoção e processamento posteriores.
Nas Seções 6.1 a 6.5, descrevemos situações que revelam algumas diferenças práticas nas particularidades de implementação entre o Arena (que usa a linguagem e o processador SIMAN), o ProModel, o GPSS/H, o AutoMod, o SLX, o ExtendSim e o Simio. Nenhuma das abordagens alternativas mencionadas é intrinsecamente "certa" ou "errada". O modelador simplesmente deve estar ciente da alternativa em vigor no software de simulação que está sendo usado e trabalhar com ela para produzir o resultado desejado. Caso contrário, é possível modelar erroneamente uma situação e talvez não se dê conta disso. Na Seção 6.6, comentamos sobre como o conhecimento dos aspectos internos do software é necessário para fazer uso eficaz das ferramentas de verificação de modelos. Por fim, na Seção 6.7, destacamos que o conhecimento dos aspectos internos ajuda a entender o monitoramento do desempenho.
Suponha que um trabalho em uma loja de trabalho flexível libere uma máquina (pela qual outros trabalhos estão esperando) e, em seguida, como sua próxima etapa, decida capturar novamente essa máquina. O trabalho recuperará a máquina imediatamente ou um trabalho em espera (mesmo que menos qualificado ou igualmente qualificado) recuperará a máquina? O que interessa aqui é a ordem dos eventos após a liberação de um recurso. Há pelo menos três alternativas: (1) Juntamente com o evento de liberação do recurso, há a escolha imediata do próximo usuário do recurso, sem que a entidade liberadora tenha ainda realizado sua próxima etapa; (2) A escolha do próximo usuário do recurso é adiada até que a entidade liberadora tenha se tornado potencialmente uma concorrente; e (3) Sem dar atenção a outros concorrentes, a entidade liberadora recaptura o recurso ocioso imediatamente. Arena, ExtendSim e Simio (o comportamento padrão) implementam (1). O ProModel implementa (2). O GPSS/H e o AutoMod implementam (3) por padrão. No SLX, usando uma variável de controle como o estado do recurso, o resultado também é (3). (Em algumas das ferramentas, os modeladores podem implementar construções de recursos de nível superior ou usar instruções adicionais para que os modelos se comportem de acordo com a escolha do modelador nesse aspecto).
Suponha que duas entidades com atraso de condição estejam aguardando em uma lista de atrasos porque nenhuma unidade de um determinado recurso está ociosa. Suponha que a primeira entidade precise de duas unidades do recurso, enquanto a segunda entidade precisa de apenas uma unidade. Agora, suponha que uma unidade do recurso fique ociosa. As necessidades da primeira entidade da lista ainda não podem ser atendidas, mas as necessidades da segunda entidade podem. O que acontecerá? Há pelo menos três alternativas possíveis: (1) Nenhuma das entidades reivindica a unidade de recurso ociosa; (2) A primeira entidade reivindica a unidade de recurso ociosa e espera por uma segunda unidade; e (3) A segunda entidade reivindica a unidade de recurso ociosa e migra para o estado pronto. Como na Seção 6.1, cada uma dessas alternativas entra em ação nas ferramentas consideradas aqui. Arena (SEIZE) e ProModel (GET ou USE) implementam (1) e (2), respectivamente, por padrão. AutoMod (GET ou USE), GPSS/H (ENTER ou TEST) e SLX (WAIT UNTIL em uma variável de controle) implementam (3) por padrão. O ExtendSim também implementa (3) por padrão. Mas o ExtendSim dá ao modelador a opção de implementar localmente (1) para os recursos especificados pelo modelador. O modelador faz isso marcando a opção "Only allocate resource pool to the highest ranked Item" para cada um desses recursos. O Simio permite que o modelador selecione a opção (1) ou (2) usando a propriedade Number of Objects e a opção "repeating resource seizes" com a etapa Seize.
Suponha que a entidade ativa queira ceder o controle a uma ou mais entidades Ready-State, mas depois precise se tornar a entidade ativa novamente antes que o relógio da simulação tenha avançado. Esse cenário pode ocorrer, por exemplo, se a entidade ativa tiver aberto um interruptor que permita que um conjunto de outras entidades passe por um ponto no modelo e, em seguida, precise fechar novamente o interruptor depois que o movimento de avanço das outras entidades tiver sido concluído. Como exemplo, considere um caso em que um grupo de caixas de sorvete com sabores idênticos deve ser transferido de um ponto de acumulação para um transportador que leva a uma operação de embalagem de um sabor por caixa.
No Arena, o efeito pode ser realizado aproximadamente com um DELAY que coloca a entidade ativa em um estado de atraso de tempo por um tempo simulado arbitrariamente curto, mas diferente de zero. No ProModel, "WAIT 0" pode ser usado para colocar a entidade ativa de volta no FEC. A entidade será retornada posteriormente (tempo de relógio de parede, mas no mesmo tempo simulado) pela CUP para o estado ativo. No GPSS/H, o Xact (Transação) ativo pode executar um bloco YIELD para migrar imediatamente do estado ativo para o estado pronto (posicionado em último lugar em sua classe de prioridade) e forçar o reinício da varredura do CEC. Os Xacts de CEC com classificação mais alta têm, então, a chance de se tornarem ativos antes que o Xact de rendimento se torne ativo novamente no mesmo tempo simulado. SLX (YIELD), AutoMod (Wait For 0) e Simio (Delay step with Math.Epsilon) oferecem soluções em que o Puck (SLX), Load (AutoMod) ou Token (Simio) ativo é deslocado para o final de sua classe de prioridade no CEC, onde aguarda para se tornar a entidade ativa novamente antes que o relógio seja avançado. No ExtendSim, "ceder e, eventualmente, retomar" faz parte da arquitetura. Uma mensagem é enviada por meio do conector de bloco apropriado quando um item entra ou sai de um bloco. Essa mensagem se propaga para outros blocos conectados, talvez alterando o status do sistema ou movendo itens de um bloco para outro como resultado. Quando o bloco de origem recebe a resposta, ele continua processando o item original.
Todas as linguagens oferecem um recurso de atraso de tempo para a espera FEL. Isso funciona bem quando uma entidade precisa esperar até que um valor de relógio conhecido seja atingido. Mas e se uma entidade precisar esperar por uma condição composta que envolva o relógio, como "esperar até que um buffer de entrada especificado esteja vazio ou sejam exatamente 17:00?" Uma abordagem típica para isso é clonar uma entidade fictícia ("sombra") para fazer a espera baseada no tempo. O gerenciamento dessas entidades fictícias pode ser complicado, especialmente para regras muito complexas. O ProModel não usa polled waiting, portanto, uma entidade fictícia seria a melhor abordagem disponível. (Caso contrário, a condição não seria verificada até que o outro componente da condição composta tivesse uma alteração de valor). O ExtendSim também não usa polled waiting, portanto, uma situação semelhante se aplica ao ExtendSim, e qualquer bloco que possa agendar eventos pode ser usado. Com o Simio, os objetos de entidade podem ter vários tokens associados, cada um aguardando um componente diferente da condição composta. Esse conceito é semelhante ao uso de uma entidade fictícia, mas não requer uma entidade adicional.
Quando houver um mecanismo de espera por sondagem, se uma única entidade tentar esperar por uma condição composta que envolva o relógio, poderá surgir um problema interessante. Isso ocorre porque o próximo tempo de sondagem pode não corresponder ao tempo do relógio de destino. O Arena e o AutoMod detectam a veracidade das condições compostas por meio de seus mecanismos de sondagem no final do EMP. O GPSS/H também detecta a verdade por meio de sua versão de polled waiting (refusalmode TEST). Mas, na ausência de algo que espere no FEL até exatamente as 17:00 (ou seja, a abordagem recomendada acima para o ProModel, ExtendSim e Simio), todas essas três ferramentas estão sujeitas à possibilidade de que o primeiro EMP que detecta a condição verdadeira ocorra quando o relógio tiver um valor maior que 17:00 horas. Isso pode ser problemático se a exatidão das 5:00 PM for importante.
O SLX reconhece o relógio como um alvo de wait-until relacionado. Um WAIT UNTIL usando um valor de relógio futuro de uma forma que contribua para a falsidade da condição fará com que o Puck seja programado no FEL para forçar um EMP no horário exato referenciado. Isso resolve o problema do tempo maior do que o desejado. Observe que esse Puck também pode estar aguardando em uma ou mais listas de atraso.
Suponha que muitas entidades estejam aguardando para capturar um determinado recurso, enquanto uma entidade controladora criada pelo usuário está aguardando a condição composta "o status do turno é 'fora do turno' e o número de espera é menor que seis e o recurso não está em uso no momento" para realizar alguma ação (como desligar o recurso, em linguagens que permitem que entidades definidas pelo usuário desliguem recursos; ou exibir uma mensagem de status). Como podemos garantir que a entidade controladora será capaz de "passar na frente" das entidades em espera no momento simulado apropriado (antes que o recurso ocioso seja recapturado)?
Uma maneira de lidar com isso seria por meio de prioridades de entidades em linguagens que oferecem esse recurso. Entretanto, conforme descrito abaixo, isso pode não funcionar mesmo que o controlador tenha uma prioridade relativamente alta. A questão principal é o método usado para implementar a espera. Se for "relacionado" para as entidades que estão esperando para capturar o recurso e "sondado" para a entidade controladora que está esperando a condição composta (é isso que queremos dizer com o termo "espera de modo misto"), as coisas podem se complicar. Toda vez que o recurso ficar livre, uma nova entidade será selecionada em uma lista de atrasos imediatamente no Arena e por meio do CEL no AutoMod, em ambos os casos precedendo a verificação de fim de EMP para condições de espera pesquisadas (e, portanto, ignorando a prioridade da entidade do controlador). Há maneiras de contornar isso, se desejado, como usar um tipo diferente de operação para forçar uma espera pesquisada para entidades que desejam usar o recurso.
No GPSS/H, usando um controlador de alta prioridade Xact em um bloco de teste em modo de recusa, o controlador espera na frente do CEC. O recurso RELEASE aciona um reinício de varredura e o controlador faz seu trabalho. No ProModel, não há espera por sondagem, mas pode haver espera relacionada a condições compostas envolvendo variáveis. As variáveis teriam de ser definidas e manipuladas para cada elemento da condição booleana e, para garantir a igualdade de concorrência, as entidades que esperam para capturar o recurso também poderiam ter de usar WAIT UNTIL em vez de GET ou USE. Outra possibilidade com o ProModel seria fazer com que a entidade que libera o recurso faça alguma verificação de estado imediatamente (tornando-se, de fato, um substituto para o controlador). Isso é possível devido ao método de seleção diferida usado pelo ProModel (consulte a Seção 6.2).
Na espera relacionada do SLX, um Puck aguardando uma condição composta será registrado nas listas de atraso daquelas (e somente daquelas) Variáveis de Controle que estão contribuindo para a falsidade da condição. A arquitetura SLX (na qual somente as Variáveis de Controle globais ou locais e o relógio podem ser referenciados em qualquer tipo de espera condicional no nível mais baixo) garante que já haverá Variáveis subjacentes às alterações de estado que estão sendo monitoradas. O modelador as define como Variáveis de Controle.
Assim como no ProModel e no SLX, o ExtendSim usaria a espera relacionada para detectar e responder imediatamente a uma alteração na condição composta. Como a alteração do estado do recurso é imediatamente transmitida como uma mensagem antes de o recurso ser realocado, essa mensagem pode ser usada para controlar a sequência e a lógica da seleção de itens. Um recurso não é alocado a menos que haja espaço a jusante para um item e disponibilidade de recurso, portanto, o bloqueio do caminho de saída de uma fila impedirá a alocação do recurso.
No Simio, os objetos de recurso podem ter sua própria lógica implementada usando processos complementares, portanto não há necessidade de usar "entidades controladoras" para implementar o mecanismo de controle. Nesse caso, os processos complementares "Off-Shift" e "Released" podem ser usados para verificar a condição complexa que envolve o status do turno, o tamanho da fila e o status do recurso. Observe que isso é equivalente à espera relacionada, pois a condição só será verificada quando o recurso sair do turno e/ou quando uma unidade de capacidade for liberada.
Agora comentamos brevemente por que um entendimento detalhado de "como o software de simulação funciona" dá suporte à sondagem interativa do comportamento do modelo de simulação. Em geral, os modelos de simulação podem ser executados interativamente ou em modo batch. As execuções interativas são úteis ao verificar a lógica do modelo durante a construção do modelo e ao solucionar problemas de um modelo se ocorrerem erros de execução. O modo em lote é usado para fazer execuções de produção.
As execuções interativas colocam uma lente de aumento em uma simulação enquanto ela é executada. O modelador pode acompanhar a entidade ativa passo a passo e exibir as listas de eventos atuais e futuros e as listas de atrasos e gerenciadas pelo usuário, bem como outros aspectos do modelo. Essas atividades produzem percepções valiosas sobre o comportamento do modelo para o modelador que conhece os conceitos subjacentes. Sem esse conhecimento, o modelador pode não tirar o máximo proveito das ferramentas interativas do software ou, pior ainda, pode nem mesmo usar as ferramentas.
Os experimentos de simulação podem consumir uma quantidade considerável de tempo do computador. Se tudo o mais for igual (inclusive a habilidade do criador de modelos), os requisitos de tempo de computador dependem do projeto e da implementação do software usado para criar modelos. O desempenho é uma questão importante o suficiente para motivar alguns softwares de simulação (por exemplo, ExtendSim; SLX; e Simio) a fornecer perfis de desempenho que, por exemplo, podem produzir histogramas mostrando onde o tempo de CPU é gasto durante a execução do modelo.
Muitas das informações contidas neste documento foram fornecidas pela equipe do fornecedor. Os autores agradecem o apoio de Deb Sadowski; Vivek Bapat; Charles Harrell (ProModel); Kenneth Farnsworth e Tyler Phillips (AutoMod); Robert C. Crain e James O. Henriksen (GPSS/H e SLX); David Krahl (ExtendSim); e David T. Sturrock e C. Dennis Pegden (ambos originalmente da Arena/SIMAN e agora da Simio).