CS333 Lab A-3:
Distributed Discrete Event Simulation

Goals of this lab:

Lab Guru:

For questions about this lab, contact Xiaoyong "Kevin" Liu, xl1@cs.wustl.edu, or the instructor.

Introduction:

A discrete event is something that occurs at an instant of time. For example, pushing an elevator button, starting of a motor, stopping of a motor, and turning on a light, are all discrete events because there is an instant of time at which each occurs. Activities such as moving a train from point A to point B are not descrete events because they have a time duration. However, we can model an event like this as two separate discrete events: the event of the train leaving point A, and the event of the train arriving at point B. If we associate a time value with each discrete event, then we can model the duration activities as the difference between the times associated with the events marking the beginning and the end of each activity. For example, we can specify that the arrival at point B occurs 3 hours and 37 minutes after leaving point A. Therefore, we can see that if the train leaves point A at 7:53pm, then it will arrives at point B at 11:30pm.

The purpose of a discrete event simulation is to study a complex system by computing the times that would be associated with real events in a real-life situation. In the train example above, suppose that we know that when the train arrives at point B, a load is transferred to a second train that arrives at point C after 45 minutes. That is, the second train's departure from point B is triggered by the first train's arrival, and the arrival at point C occurs with a delay of 45 minutes after the departure from point B. In this simple example, we can use discrete event simulation to determine that the second train will arrive at point C at 12:15am.

One way to carry out a simulation is to use the real-time clock (the clock on the wall) to time the delays, and to read the value on the clock as each event completes in order to see what would happen. However, this would take unnecessarily long. For example, it would be silly to wait 3 hours and 37 minutes to determine the arrival time of the first train when a simple calculation suffices. So, the idea of a discrete event simulation is to compute, as quickly as possible, the physical times that "would" occur in real time in a physical system, but without actually waiting for the delays between events to occur in real time.

To accomplish this in a sequential program, one uses a queue of events that are ready to be performed. This event queue is kept sorted in increasing time order, and the program processes the events in increasing time order. The program is started with one or more events initially in the queue, and has built-in knowledge about how each kind of event causes other events to be added to the event queue. (For example, it may know that if one event occurs at time t, then a related event should occur 5 time units later, at time t+5, so it would put that new event in its queue.

When simulations grow large and have a lot of concurrency (have many events that could be processed simultaneously), it can be helpful to distribute the work of processing events across many simulators, with each simulator responsible for processing certain kinds of events. Like the sequential version, each simulator maintains its own event queue and processes events in time order. Some events may cause new events to be put into the local event queue. However, some of the events may need to be sent elsewhere for processing.

Each simulator may proceed independently, processing events in its event queue. It is not a problem if some of the simulators are "ahead" of others in terms of the times that they are assigning to events. In fact, this is desirable. However, the trick is that you must guarantee that no simulator receives an event whose time is earlier than any event already processed by that simulator, because otherwise the events would be processed out of order. Another way of saying this is that we cannot allow time to go "backwards" at any of the simulators.

In an "optimistic" approach to distributed discrete event simulation, one assumes that such a problem will not occur, and, if a problem does arise, it "rolls back" the simulation to an earlier point and restarts from there. However, we will use a "conservative" approach, in which we will guarantee that events cannot arrive out of order. In other words, before it processes an event with time t, a simulator must be certain that it will not be receiving any more events to process with times earlier than t.

We assume that each simulator knows the set of "incoming neighbors" (simulators from which it might receive events). If a simulator knows that the current simulation time of each of its incoming neighbors is greater than time t, then it is safe for the simulator to process events at time t or earlier. Sometimes, this knowledge is available automatically: if a simulator has already received events with times greater than t from each of its incoming neighbors, then it is safe to advance its local simulation to time t. However, if a simulator does not receive an event with time greater than t from one of its neighbors, it may have to wait indefinitely before processing the next event. There are many possible approaches to solving this problem, and every solution some advantages and disadvantages. We will let you decide on your own solution to this problem, but here are some ideas.

Directions:

Be sure that you have read the introduction carefully. Then read over the rest of the assignment before starting.

  1. Overview of the Simulated System: In this project, you will construct a distributed discrete event simulation of a car wash. The car wash is viewed as a message-passing system consisting of several distinct components: a source where cars enter the system, two or more physical car wash stations, an attendant who decides where each car should go, and an exit where cars leave the system. A schematic diagram of message communication among these components is given below.

    The components have the following functionality:

  2. Sequential simulator (optional): (As a stepping stone to your distributed discrete event simulation system, you may want to start by implementing a sequential discrete event simulator. You will not turn in this part of the assignment, so you may be tempted to go straight to the distributed version. However, at a minimum, you should understand how you would design the sequential version before tackling the distributed one.)

    Implement a sequential discrete event simulator. The parameters of your program should be: the number of car wash stations, the processing time of each station (separately), the range of random numbers chosen for the arrival times of the cars (smallest random number and largest random number), and the closing time (when the source will stop sending new cars into the system). Note that two par ameters are used for the car source to generate cars, allowing you to control both the minimum and maximum time interval between the arrival of two cars.

    Your simulator should maintain a sorted event list and process events in time order. To process each event, you should remove it from the event list, PRINT out the name of the event which includes the time at which it occurs, and insert any triggered events (with appropriate times) to the event list with the appropriate times. Remember that it is legal for one event to trigger multiple events. For example, the arrival of a car at a car wash station may cause two new events to be queued: sending a car to the exit and sending an "idle" message to the attendant.

    Each event has a sender, a receiver, content, and its associated time. For example, the event [18, attendant, Station3, Car10] denotes that the attendant sends Car10 to Station3 at time 18.

    In addition, your simulator should maintain a car queue which keeps track of the cars queued at the attendant.

    Be sure to test your sequential simulator thoroughly, especially if you plan to use the code as a building block for your distributed simulation.

  3. Distributed Simulation: Now modify your simulator so that it can be used for distributed discrete event simulation. Your main task is to implement 3 types of modules. Whenever a module removes an event from its event queue for processing, it should print out all the information about that event (time, content of message, etc.).

    In your distributed simulator, message passing is achieved by publishing a tuple whose type matches that of the message. The message can be in the form of [time, sender, receiver, content], or in the form of [time, receiver, content], or even in the form of [time, content], depending upon how you design your system.

    Note: To avoid deadlock at the end of the program, one simple approach is to let the CarSource module sending a "Terminate" (or "NULL") message after it finishes generating cars. After delivering all queued cars, the Attendant processes the "Terminate" message by forwarding the "Terminate" message to all the car washers. In this way, all modules can terminate gracefully. Otherwise, the Attendant and all CarWashers will wait indefinitely.

  4. Visualization:Using EUPHORIA, construct a simple visualization of your simulation system. For example, you could have the attendant publish it's queue length, updated over time. Also, you could have each station publish a flag saying whether or not it is busy, etc. Then you could connect this status information to Euphoria for visualization. If you want to get fancy, you could allow the user to control the input parameters for the modules (such as the random values for car arrivals, termination time, and length of time to wash a car at each station.) Keep in mind that as you watch the system, different components will be operating at different logical times simultaneously. (Even if you do a fancy visualization, you should still print out the events processed by each component.)

Further Reading:

The following paper provides an overview of distributed discrete event simulation algorithms. It includes a car wash example similar to the one in this lab.

Jayadev Misra, Distributed Discrete-Event Simulation, Computing Surveys, Vol. 18, No. 1, March 1986, pp. 39-65.


To receive credit for this lab, you should:

  1. Clean up and print out your code. (Don't turn it in, but save it for your code/design review.)

  2. Turn in a Project Evaluation Form near the beginning of class on the day you want to do your demonstration and code/design review. You should be prepared to demonstrate your working application, explain your design and code, and answer questions.