OBJECTSIM V0.4 (beta) User Guide

Arnold N. Pears
Copyright (C) Concurrency Research Group,
La Trobe University 1998

Table of Contents

 I. Getting OBJECTSIM
  1.  Installation
  2.  Software Structure
 II. Using OBJECTSIM
  1.  The OBJECTSIM Simulation Model
  2.  Command Line Environment
  3.  The Sample Experiment
  4.  Building Your Own Experiments
 III. Extending OBJECTSIM
  1. The Hierarchy
  2. Specifying Simulation Entities
  3. Example of a Simulation Library Implementation
  4. Integrating Simulation Libraries into OBJECTSIM

I. Getting OBJECTSIM

  1. Installation
  2. OBJECTSIM V0.3 has been developed for UNIX workstations. It requires the following minimum configuration.

    The current distribution has been compiled and tested on a range of SUN workstations, from SUN 360's to recent SPARC Stations. The standard distribution also runs on a DEC ALPHA XLS workstation under Linux.

    OBJECTSIM is distributed as a single UNIX tar file OBJDST_V0.3.tar. This file is also available as a gnu compressed version OBJDST_V0.3.tar.gz. To install the system you extract the tar file which will create the file system ./OBJECTSIM/Dist, and unpack the distribution into the resulting Dist directory. You should cd to the Dist directory and follow the customization and installation instructions contained in the README file there.

    Assuming that you have downloaded the compressed source files a normal sequence of instructions to do this is.
     

      host> gunzip OBJDST-V0.3.tar.gz
      host> tar -xvf OBJDST_V0.3.tar
      host> cd OBJECTSIM/Dist

    Once you have unpacked the sources and created all the rest of the required file system in the process you should cd to the OBJECTSIM/src directory and type make. This builds all the  kernel and object libraries supplied with the standard installation and distributes them appropriately. This also builds the OSim executable and places it in the OBJECTSIM/bin directory.

    Finally you need to edit your .cshrc file and update it as instructed in the README. Don't forget to add the OBJECTSIM/bin directory to your PATH variable. Please contact your local system administrator if any of the steps in the README or these instructions are unfamiliar to you or you wish to have a commonly available version of OBJECTSIM. Since OBJECTSIM is still under development we ask you to please register your copy of OBJECTSIM for tracking purposes, and so that we can assist you with future releases.

    NOTE: OBJECTSIM is not a commercial product, so support maintenance and development are entirely at the discretion of the research team using OBJECTSIM. No warranties or product guarantees are made or should be inferred from the distribution of this software.
     

  3. Software Structure
  4. After installing OBJECTSIM you should have the file system shown in figure 1 below. This section of the manual explains the function of each directory, and prepares you to compile the sample experiment that is included with the distribution.

    OBJECTSIM Directory Tree

    The major directories that are created by installing OBJECTSIM contain all the sources and libraries required to create OBJECTSIM itself, and then use it to configure and execute simulations. Building the OBJECTSIM suite creates libraries which support the construction of simulations based on the objects included in the standard distributions, and also distribute the header files which define the interfaces with simulation objects, and the OBJECTSIM kernel source files.

    The current distribution supports basic modelling of multistage interconnection networks (MIN's). It defines two by two unbuffered crossbar switches which can be connected to each other to form standard types of MIN. Banyan switches with various levels of buffering and multicast capability are also implemented in the base object library.

    The libraries are stored in the directory OBJECTSIM/lib and the headers are all copied from the relevant source locations to OBJECTSIM/include. If you want to look at the C++ interface for any simulation or kernel class you should go to the include directory and look at the header files there.

    The OBJECTSIM kernel code is separated into two logical components. Kernel code and model code. The kernel code manages the model object instances, and the model library code defines the classes in the model object libraries from which object instances are created and connected to form simulations. The installation includes the standard model libraries we have developed for network and computer architecture simulations. Models of new object classes added during your research should be implemented as new model source files using standard interfaces inherited from the basic OBJECTSIM hierarchy. Building your own simulation objects and libraries and integrating them into OBJECTSIM is described in  Section III .

    We expect additional libraries to become available from the OBJECTSIM web site as people apply the methodology to their own application areas. Since one of the major objectives of OBJECTSIM is to encourage code reuse in the simulation community it is hoped that people using the tool will submit their libraries to this Web site for use by the OBJECTSIM community.
     

II. Using OBJECTSIM

  1. The OBJECTSIM Simulation Model
  2. OBJECTSIM consists of a simulation kernel and a generic object class from which all simulation entities are derived. This allows OBJECTSIM to provide generic support for event driven simulation of any system that can be modelled as a set of interacting entities. In essence the simulation model assumes a collection of entities, each of which is a state machine responding to external events. Typical responses to events include generating future events, changing internal state. The execution model assumes that all data items are associated with an event. However, this event model does not assume that every event has data associated with it, since meta-events, and control events are not usually associated with data exchange between simulation entities.

    Simulation entities are completely generic, and have no concept of the structure of the overall system of which they are a part.  They merely respond to events that are delivered to them. This approach to simulation of concurrent systems relies on the definition of an extremely powerful generic hierarchy of simulation entities. All OBJECTSIM simulation entities are derived from a single base class, which completely defines the interface between these entities, the simulation kernel, and all other entities. This derivation allows simulation architects to focus on specifying a behavioural model of the simulation entities with no concern for the entity interconnections and other issues associated with the structure of the overall system being modelled.

    To arrive at this level of genericity OBJECTSIM uses the concept of virtual PORTS to specify abstract entry and exit points for an entity. These ports are used in each entitiy to accept inputs and store outputs.  The implementations of  generic simulation entities consume messages from input ports and generate messages on output ports.  When a system architect designs a new simulation entity s(he) will derive a new object type from the base class Object,  specify how many input and output ports it has, and provide an implementation for a virtual function called Execute().  The code of the Execute() function defines how the new entity will react to input messages, including forwarding messages to output port or generating new messages on output ports.  Consequently, when designing a new class of simulation entities for OBJECTSIM one need only decide on the structure of that particular entity, and provide an interface through which that entity communicates with the external environment.

    The overall structure of a simulation for a complex system is defined by establishing relationships between object instances (entities/agents). Output to input port correspondences for each simulation agent are specified when a system model is constructed. Port correspondences are registered with the OBJECTSIM kernel Routing manager which handles the transfer of Events between agents. Currently the registration of port mappings and the construction and supply of object instances to the kernel must be handled by the user, however, a Visual Simulation design interface is planned for release with OBJECTSIM V0.5.
     

  3. Command Line Environment
  4. OSim can be configured to run experiments by issuing commands to a command line environment, or by specifying options at runtime. Combinations of runtime and command line options can also be used. This section describes the commands that can be used at the OSim prompt.

    When you run OSim as a stand alone environment a prompt appears, and commands can be used to load experimental configurations and execute them. The available commands can be listed at any time by issuing the command "help" at the prompt.

    The command line environment also allows the user to configure OSim in a cluster computing environment, adding additional hosts, and running parallel simulations on the workstation cluster.

    Current OSim commands are

    Many of these commands have runtime option equivalents. All the runtime options are listed in the manpage and are also listed using the "-h" runtime option to OSim.

  5. The Sample Experiment
  6. Some sample configuration files that can be used to test OSim, and familiarize oneself with the OSim runtime environment are located in OBJECTSIM/experiment. This section describes how to start OSim and run an experiment and explains the features of OBJECTSIM that you need to understand to do this. The upgrade from V0.3 to Version 0.4 makes OBJECTSIM a runtime simulation environment that can be customized to execute any simulation consisting on object instances constructed from an OBJECTSIM library.

    Previous releases of OBJECTSIM used module libraries and compiled and linked the main simulation kernel to the library which provided the object definitions and a main routine (written by the experimenter) that constructed the simulation experiment's object instances and initialized the simulation kernel. From V0.4 onwards the approach is completely different. To run an experiment you invoke OBJECTSIM and load simulation configuration files using either command line options or by issuing instructions to the OBJECTSIM environment command interface.

    To run the basic experiment type "OSim -f test.ocf" in the OBJECTSIM/experiment directory. This automatically starts the objectsim environment and loads the default experiment.  Note, OBJECTSIM configuration files are expected to terminate with the extension .ocf and the environment checks the file extension and some internal format during loading. An experiment can be loaded at invocation using command line options to select a configuration file, or by issuing commands at the command prompt once the basic kernel has been booted.

    To run the "test" experiment you type "run" or "go" at the command prompt since all the configuration and simulation objects were loaded during bootup using command line options supplied in a startup script. This test experiment consists of the most simple simulation possible. A statistical source object (generating message packets) is connected to a statistics collection object (which consumes and counts packets received). The output of the simulation is data which indicates how many packets were generated at the source, and information from the consumer object shows how many packets were recieved and the distribution of destination addresses of the packets collected.

    The experiment directory contains two configuration files that are a useful guide to creating and executing your own simulations. If you are only going to use the standard objects provided with OBJECTSIM you need only consult the section which defines all the standard objects and their interfaces, and copy and modify the experiment directory script files using them as a template for creating your own simulations.

    Each simulation consists of a number of simulation objects and a wiring plan that specifies how the input and output ports of each object are connected so that events can flow between the objects.  The structural representation of the test experimental system is shown in figure 1.

    MaxPrts 2
    MaxObjs 2
    
    StatCPU 1000 0 2
    NetSink "Received Packets" 4
    END
    RouterEntry 0 0 0 0
    RouterEntry 0 1 1 0
    
    Event 0 0 0 0 0
    

    The first two lines in the script specify the number of objects in the system, and the maximum specified number of ports in any object that is used by the simulation. These figures are used to define the size of the routing table that describes how objects communicate with each other. These two quantities can occur in any order, but must be given as the first two lines of any configuration file.

    The next section of the simulation configuration file specifies the parameters to be used to create each object in the simulation. Each line represents an object and the objects are assumed to be numbered from zero to MAX_OBJS. This numbering scheme is important since it is used to set up the routing table. Each Object of the file consists of the Object name first and then the user parameters that can be supplied to the constructor of that object. The system does limited checking against some internal information to check that the object name and number of parameters are legal. This section must be terminated with an "END" on a single line.

    The next section of the file specifies the routing entries used to connect the ports of the simulation's objects together, forming a final system architecture. Each routing table entry begins with the string RouterEntry which is followed by four parameter values. Each router entry consists of two tuples (OId,Port). To wire the objects together each RouterEntry specifies an output tuple, and the input tuple which represent the two end-points of a connection.

    In the test example there are two entries. The first is the self activation event flow for the StatCPU object, and you can see that the connection is between (0,0) and (0,0), meaning that events exiting object zero via output port 0 should be delivered to objects 0 input port 0 at some time in the future. The second entry is (0,1) to (1,0), meaning that events leaving object 0 on output port 1 should be delivered to object 1 input port 0. This configuration is shown as an object wire diagram in the figure below. A more complicated example is given in section ???.

    When simulation objects are implemented the input and output ports for different types of operations are specified by the designer. By referring to the specifications in the library documentation one can decide how to connect the ports of objects together to realize the system design we wish to simulate.

    When you type "go" at the OSim prompt, this invokes a simulation kernel method that delivers events to the simulation objects and selects them for execution. Events, and therefore objects, are selected in time-stamp order for execution, and the simulation terminates when there are no events to be delivered. At this point the Kernel reports the GVT of the system and returns to the prompt.

    Gathering and display of performance statistics for each object in the system can be implemented by writing code in the DumpStats() methods of the simulation objects to collect and report/store any information that is required. At present this data is summary information and it is not really possible to use this facility to dump out progressive statistics. Progressive information can be collected by instrumenting the Execute method of the object to print information to the screen, or to dump information to a file. Future versions of OBJECTSIM hope to provide integrated data visualization facilities, but such facilities are not scheduled for inclusion in releases of OBJECTSIM in the near future.

  7. Building Your Own Experiments
  8. Using the standard libraries to build experiments begins by selecting the simulation objects that are required. Next create a logical communication schematic of the architecture similar to that shown for our sample experiment. This will help you to build a correct routing table. This step will be automated when we release the visual design interface integrated into OBJECTSIM V0.5.

    To create an experiment, create a configuration file and list the objects you need, and instruct the router on how they are connected together. Once again, the test experiment code provides a useful guide on how to do this.  To load your new experiment invoke OSim using the -f runtime option or the command line to load your file. Type "go" at the command prompt to execute your model.

    The standard library objects collect and display predefined statistical information that was considered of interest to the designers. If you require other statistics or need access to objects which are not defined in the standard libraries you will need to create new simulation model library code to implement new simulation object classes, or derive and refine new object classes from the existing objects in order to adjust the definitions of existing objects to fulfil your requirements.

    When you do so, we suggest that rather than changing the implementation of the standard objects, you inherit their structure and build new object libraries to meet your needs. By using the inheritance features of C++ in this way you can maximize the benefit of using other people's code, without compromising the integrity of the basic OBJECTSIM library hierarchy.

    The next section is a step by step guide to extending the OBJECTSIM hierarchy, and writing new libraries of simulation objects that are derived directly from the three basic node classes. Please read this section before you start to implement new OBJECTSIM classes to ensure that your new simulation objects will be compatible with the simulation kernel. If you decide to extend the OBJECTSIM hierarchy please consider submitting your extensions and new class libraries to the OBJECTSIM web site to enhance the system and assist other users.

III. Extending OBJECTSIM

  1. The Hierarchy
  2. The OBJECTSIM simulation model is based on a simple and powerful hierarchy of simulation objects. This methodology proposes single high level interface for all objects (node), and derives three basic classes of object from this single entity. The fundamental entity of a simulation is a Node, a simulation node will be one of three basic types, a source, forward, or sink for events. The node types may be briefly characterized as follows:-

    1. Source nodes are primarily creators of events, they feed data and events to other objects.
    2. Forward nodes respond to events and transform the associated data generating another event as a result.
    3. Sink nodes respond to incoming events by consuming them and their data without generating any other events as a result.
    A graphical representation of the hierarchy and some of its high level specialization's can be found in the picture below which is extracted from one of the research papers on the development of OBJECTSIM.
    OBJECTSIM Modelling Hierarchy
    In fact, the logical sub-classes of Object (source, forward, sink) are not sufficiently different in interface to require the creation of individual virtual classes. They exist as a purely logical separation of functionality, enabling the system modeller to more clearly compartmentalize and classify objects while creating the abstract design of a system. In actuality these three conceptual entities are realized by a single C++ class Object. This class provides the basis for all simulation entities, and pointers of type Object * can be used to refer to any simulation model entity as a result. The Object class also defines the interface between simulation objects and the OBJECTSIM kernel. This allows the kernel to handle all the instances of simulation entities in a completely generic manner.

    The Object class also specifies the interface used for all interaction between simulation model entities. Additional private and public methods can be added to classes derived from the virtual class Object, but these methods are not accessible to the Simulation Kernel and should not be used to communicate directly between derived object classes as this contravenes our "prime directive"; which is to maintain complete object genericity, and independence. This means that no object implementation should have any knowledge about the methods or data types of other objects, with the exception of Events.

     The standard interface provides input and output Event lists for each object, and a virtual function Execute, which is overridden in the derived classes to provide the functionality of the new object class. The Execute function of a derived class will normally use additional private methods specific to that class to process the incoming messages and events, and generate additional events if required. Data transfer between entities is handled by attaching the data to an Event, and Posting it to a port. How that data is unpacked by the receiver depends entirely upon the functional definition of the receiving object. Obviously objects that exchange data will have a protocol which allows them to interpret each others data, but we leave details of this nature to the end user.  To facilitate generic data transfer OBJECTSIM events pass all data content as a void *, thus data consistency and memory allocation for explicit data transfer between objects is entirely an end user issue.  An example of data exchange piggy-backed with event exchange is provided in the standard network object library objects. For example see the implementations of SlotBus, and TwoMIN in the model directory file base.cc.
     

  3. Specifying Simulation Entities
  4. To design a new simulation entity you must inherit the basic interface of a simulation object by including the header file sim_obj.h, and deriving your new class from the basic OBJECTSIM class Object. As previously noted new simulation classes must be derived from this base class to ensure compatibility with the Kernel implementation.  Of course additional attributes and methods can be added to the derived classes to implement their new functionality using the standard C++ syntax.  However it should be noted that the basic functional definition of a derived class must be implemented by overloading the Execute virtual function of the base class Object. A pictorial representation of the important features of the  OBJECTSIM Object showing the major interface entry and exit points and the principal attributes is given below.  This is not a complete specification. The intention is to give an overview of the important aspects of the OBJECTSIM Object model in order to facilitate understanding of the fundamental techniques. A full interface specification in C++ can be found in the file OBJECTSIM/include/sim_obj.h.

    Object Model
    Having described the basic structure of an Object, we can move on to describe how to create new objects. In essence all one does is inherit the basic interface as outlined above. The code to define the header file <MyNewClass>.h for this new class uses standard C++ functional inheritance as outlined below.
      The implementation of the private methods for this new class, and the specification of the Execute method can now be specified in an associated <MyNewClass>.cc file. The next section provides an overview of the existing code files in the OBJECTSIM/model directory for base.h and base.cc as an example of the format and general techniques used to write OBJECTSIM model objects.

    WARNING:

    A rather nasty feature of the current OBJECTSIM implementation is that event creation and deletion are handled expicitly in the code that defines the implementations of behaviour. That is you will create and Post an event using code similar to the following
     

           Event *msg=new Event(getOid(), i+1, pkt_out[i], 1, getClock());
           Post( msg );
    These events will be collected by other objects and processed, and quite often other events will be generated as a result, however it is important to remember that events must be properly disposed of after the data contents (such as a network packet) if a content exists, has been extracted and stored properly.  In the context of the MIN example used in the next section this code looks as follows.
     
           // recover the event that triggered me and decide how to use it
          Event *evt= Collect();
          evt->getDestinData( d_oid, i_port );
          tmp= (Packet *)evt->getContent();

          // Update clock, memorise it locally, and generate output events
          setClock( evt->getTime() );
          clk= (int) getClock();

          // Delete event
          delete evt;


     
  5. An Example of a Simulation Library Implementation
  6. As indicated this section is devoted to explaining the structure of a sample simulation library. The intention is to provide more information about how a simulation library should be designed and implemented in OBJECTSIM.  The complete implementation of the library code is found in the files $(LOCATION)/OBJECTSIM/src/model/base.cc and base.h in your installation.

    The objects in the base simulation library implement very simple objects which provide source address streams, switches and output packet collectors for a very simple model of a Multi-stage Interconnection Network (MIN). In this model we have defined three object types which will be used to implement a MIN network of any size, and then evaluate the packet loss, throughput and average delay for that network.  The generic nature of OBJECTSIM simulation components means that we can build an arbitarily large network by creating instances of the three primary object classes. The object classes and their function in the simulation model are summarised in the following table.
     
     

    Object Name Description
    StatCPU A source object that generates data packets to a destination addess on the other side of the MIN. Destination addresses are generated using a standard statistical model based on random number generation.
    TwoMIN Two input crossbar switch with no buffers. Since the switch has no information about what stage of the MIN it is in it has to interrogate the packet that it is switching to discover how it should treat that packet.
    NetSink A statistics object that collects and disposes of the data packets as they leave the MIN. Packets can leave the MIN when they are dumped due to internal collisions or when they arrive at the destination. The implementation of a NetSink is currently just a counter of how many packets were discarded or left the network normally, and the average time those packets spent in the network.

    The MIN that is defined in the expts directory in the file min.cc is a two stage min constructed from four switches to which are connected input generators and output data collectors. The conceptual design for this experiment is shown in the figure below.



    However the figure above (while an accurate depiction of the system to be modelled is not the most efficient way to construct a model of this system from the objects we have defined, and to collect the appropriate statistics. Since we are interested to collect a summary of the output and discarded parket information the actual simulation model that we have used in the experiment is the following.

    This conceptual simulation model is finally implemented using an inter-object communication pattern that is almost identical to that shown above. The only difference is that self execution loops are added to the StatCPU instances to ensure a steady stream in input packets.

    Having defined the simulation model as shown the final step is to implement the functionality of each of the object classes required. The following subsections deal with the key issues involved in designing each of the objects in turn, and also discusses the need for a packet data structure which can store state information so that appropriate statistics can be collected by the model objects.
     

  7. Integrating Simulation Libraries into OBJECTSIM
  8. Once you have designed and implemented new simulation objects and tested them you will need to link these objects into the OBJECTSIM libraries so that you can use them in simulations. To do this you need to follow the instructions below, which specify how to add the files you have created to the set of standard source files used to build the OBJECTSIM model object libraries. You can then include the appropriate header file into an experiment main.cc file, instantiate objects, and insert them into a kernel instance in exactly the same manner as was used in the sample experiment.

    To compile and install a new set of objects into the OBJECTSIM model libraries you need to implement your library and update the Makefile in the OBJECTSIM/model directory to include your new library as a compilation and distribution target. This will ensure that your library will be added to the standard OBJECTSIM model library archive automatically when you type make in the OBJECTSIM/model directory. It also ensures that if you collect the OBJECTSIM version you have installed and relocate it to another platform all your new sources will be automatically added to the standard distribution files and unpacked and distributed appropriately, simplifying the relocation process. In effect your new code will have become a standard part of the OBJECTSIM library collection.