How to Perform a Trace-Driven Simulation in Möbius™?


Problem Description


For a trace-driven simulation, we need to read data from a file that is subsequently used in a simulation run to determine points in time when particular events shall take place. The Möbius™ simulator draws time delays between events from probability distributions that are specified for any particular activity.

Motivation


Trace-driven simulation is frequently used to validate a simulation model against existing measurement data.
When studying how a system responds to a given workload, we produce a sequence of tasks (the workload) according to given measurement data and feed it into a system model. The observed statistical measures from that simulation run should match with measurement data from the

General Solution Idea


A timed activity with deterministic delays is used to create the arrivals of entities. The value for the deterministic delay is set according to a floating point value stored in an array of floating point values and updated whenever the activity fires.
We use an extended place named IATs that holds an array of double precision entries to hold the interarrival times and a separate state variable named IndexIAT of type integer to store an index for the current position. All interarrival times are read from a file upfront and before the simulation starts with the help of an immediate activity that is enabled rightaway but only to fire once.

Example Model:
The example model can be downloaded from here: TraceDrivenSimulation.tar.gz, it is in the format of an archived Möbius™ project. For a particular usage, one needs to configure it following these steps:
  1. Adjust the size of the double array that holds the data: The example consists of 2 atomic models. The one is a simple queueing model with exponential service times that shares a state variable "Queue" with the other atomic model that generates arrivals by reading interarrival times from a file "myIAT.txt" located in the user's home directory. The model is configured to read up to 100 values from file. To adjust the number of values to be read from file, one needs to fix the size of the array in the type definition of type IAT. To do this, open the atomic model "ArrivalsFromTrace", select Edit->TypeDefinitions and type IAT in the window that opens. Edit that type and overwrite the current value 100 by an appropriate non-negative integer value.
  2. Adjust the number of values to be read from file: Set the global variable NumberOfIATs in the Mobius Study Editor to the corresponding value. If the trace file contains 100 values, you can set this variable to any value between 1 and 100. Note: the initialization activity will stop after reading this number of values.
  3. Adjust where to read the data from: There are two options, either rename the data file to "myIAT.txt" and locate it in your home directory, or change the c++ code in the output gate OG_init in atomic model "ArrivalsFromTrace".
  4. Adjust the file format: the code assumes a format with one floating point value per line. Each value describes the time difference between consecutive arrivals (hence interarrival time).

Limitations
  1. The presentation is formulated in terms of a Stochastic Activity Network (SAN) formalism for an atomic model.
  2. The model reads all data from file upfront which limits scalability due to memory requirements to traces with millions of states.
  3. The index variable that iterates through the array is of type integer and will overflow if used on arrays with more than 2^31 entries.
  4. The model only reads a sequence of interarrival times, NOT timestamps. It does NOT handle arrivals of different kinds, e.g. for a queuing network with multiple classes.

Technicalities
  1. In order to have access to methods in the fstream library, one need to make Mobius insert a corresponding "include" statement in its generated c++ code. This is done in the sample model with a file named "myinitheader" that consists of a single line that says "#include <fstream>". This file has been put in the project directory such that Mobius includes it in a project archive. Note the pitfall: this is no model definition file such that Mobius omits it in a minimal archive and it also removes it when the user uses the "clean project" feature to remove all generated file. The "myinitheader" file is declared as an "User defined header" in the atomic model that reads data from a file.
  2. An atomic model that reads data into an double array needs to declare a double array as an additional user-defined type. Note that this type is accessible as a type for extended places only after it has been declared. So, it needs to be declared first.