The queuing network is composed from two servers with FIFO queue of transactions waiting for a service. There are two sources of new transactions and two input points for them. There are also two output points - see the figure.
We assume exponentially distributed random arrival time in input streams of transactions and exponentially distributed random service time of both servers. The corresponding parameters of the simulation model are then as follows:
Additional parameters are branching probabilities which describe passing of transactions through the network:
The output information of the model should be the response time Tq, i.e., the mean time which a transaction spends inside the network.
The construction of the model starts with object-oriented analysis of the problem. We will try to find types (i.e. classes in OOP terminology) of objects and their properties (i.e. attributes and/or methods). Moreover, we will follow the idea of reusability, so we will create more flexible types which can serve in a model of n-node network with m input streams as well. The found types are described in the subsequent items.
We decided to use a "passive" model of the transaction (the "active" possibility
means to take transaction as a process-like object). Due to the fact that we need
to engage transaction in queues, we will derive type TRANSACTION
from the supported LINK type. One more attribute
of TRANSACTION is the time when transaction was generated. According
to C-Sim syntax we have:
typedef struct {
csim_d_link;
double t_input; /* "birth" time of transaction */
} TRANSACTION;
Our queue can be derived from the supported HEAD type which
implements two-way circular list. The one more attribute of the QUEUE
type is binding (i.e. pointer) to the object-server which is taking transactions
out of the queue:
typedef struct {
csim_d_head;
PROCESS *server; /* pointer to server */
} QUEUE;
The source of transactions is evidently an "active" object which generates
a Poisson stream of transactions. It means that type SOURCE must
be derived from the supported type CSIM_PROCESS. We added attributes
lambda-parameter of Poisson stream and binding
to the queue where to put generated transactions:
typedef struct {
csim_d_process;
float lambda; /* parameter of the pdf of interarrival time */
QUEUE *queue; /* pointer to output queue */
} SOURCE;
Type SOURCE describes local data record of an instance
of the process. Moreover, we have to define a program of process' "life".
Due to the fact that the program should be the same for all instances
of source-like objects, it has to be constructed with property
of reentrancy. We will show the example of C-Sim construction
of such a program:
csim_program(SOURCE, SOURCE_PROG)
TRANSACTION *p_poin; /* auxiliary pointer */
for (;;) {
p_poin = csim_new_link (TRANSACTION);
p_poin->t_input = csim_time();
into ((LINK *) p_poin, (HEAD *) my.queue );
if (csim_idle (my.queue->server))
csim_activate_at (my.queue->server, csim_time());
csim_hold(csim_negexp(my.lambda));
}
csim_end_program
The last (and the most complex) type we need is SERVER. This type
describes data of a server-like object. Server introduces evidently an "activity",
so we derived its data type from the CSIM_PROCESS. The meaning of added
attributes is explained in comments. We have only to note that with regard
to the intended (almost) universal utilization of server objects it is convenient
"to distribute" a capability to gather statistical data across all server objects
(i.e. a server gathers statistic of transactions which are completely finished
after the service).
typedef struct {
csim_d_process;
float mi; /* rate of service, exponential pdf */
float p; /* prob. of departure after the service */
QUEUE *in_queue; /* pointer to an input queue */
QUEUE *out_queue; /* pointer to an output queue */
UWORD cnt; /* counter of serviced transactions */
double stq; /* sum of responses of finished transactions */
} SERVER;
The complete program for server processes can be found in source file oqn.c.
In order to create and set up all the model of queuing network we have to: