If you need urgent consulting help click here
Time framework
Time and performance units
Time inside the emulation is referred to as virtual time (as opposed to host time or real time) and is expressed in virtual seconds. Currently, the resolution of virtual time, i.e., the minimum expressable time quant, is 10^-6 virtual second or 1 virtual microsecond. Performance of the CPU is expressed in MIPS units (millions of instructions per second) and is an integer value. This means that setting the minimum time quant allows the CPU with performance of 1 MIPS to execute exactly one instruction.
Note
For CPU with performance higher than 1 MIPS, it is possible to execute instruction-by-instruction using a special stepping mode.
Performance of the CPU can be configured with the following command (in this case, set to 120 MIPS):
cpu PerformanceInMips 120
The default value of the performance setting is 100 MIPS.
Time sources and sinks
Objects controlling flow of virtual time are called time sources. By default, there is one time source, called master time source, assosiated with the emulation. Currently, there is no API to create other master time sources, but the framework itself is capable of handling multiple time domains (with each master time source being a root of the domain).
Objects that are aware of the time flow are called time sinks. Each sink is connected to exactly one source (at any time, although it can change sources) and awaits information about how much virtual time has passed so far.
There are objects that play both roles: sink and source - they are called slave time sources. The reason for having a slave time source is explained in the following section.
Synchronization
Virtual time flows in the form of quants generated by master time sources and granted to sinks. The value of a quant is expressed in virtual seconds (or a fraction thereof) and is configurable by the user.
Once a quant is granted to the sinks, the source waits for them to finish execution. Once all slaves have reported back, it is time for the synchronization phase. As it is guaranteed that no nodes work during this phase, it is safe to process all inter-node communication during this. Only when the synchronization phase is finished, can a new quant be granted to all sinks.
It is possible to introduce slave time sources in the domain that divides the quantum into smaller fragments and allows for tighter synchronization of selected nodes.
Time domain
A configuration of time sources and time slaves connected together is called a time domain. All members of a time domain observe the flow of the same virtual time and are synchronized together. In case of having multiple time domains the time values are not comparable between them - in other words, there is no synchronization across different time domains.
There is one time domain by default in the emulation. The master time source is associated with the emulation itself, every machine provides its own slave time source that drives the CPU(s) being a sink.
Configuration and monitoring
There are several properties provided by a time source that can be used to tune the virtual time flow:
- Quantum
The amount of virtual time between two synchronization phases. It is guraranteed that the difference of virtual time perceived of two slaves is never higher than a quantum of its closest common source.
The value of quantum can be changed between synchronization phases, but the new value won’t be used until the next grant.
The slave time source can have a different quantum than its master time source. If the slave’s quantum is smaller than master’s, the slave will split the quantum into smaller pieces and report back to master only when all the pieces are used up. If the slave’s quantum is bigger than master’s, the slave will report immediately (not executing any CPU instructions) and accumulate the granted interval until it reaches the required quantum.
It is illegal to set quantum to zero as it would not allow the virtual time to pass at all.
- Performance
Floating-point value describing the ratio of virtual to real time flow. Value of 1.0 means that the virtual time should in average pass in the same pace as a real one - the user feels like using real hardware; software that sleeps for 1 second should sleep for 1 real-world second. Value higher than 1.0 means that the virtual time should pass faster than the real one - it can be used to speed up long emulations (e.g., test what happens in the emulated system after 24 hours of uptime). Value lower than 1.0 means that the virtual time should pass slower than the real one - it can be used to slow down emulation when a lot of events is happening in a short period.
The performance of the host machine puts a natural limit on an effective values of this parameter (see
CurrentLoad
). It is possible to temporarily overwrite this setting by usingAdvanceImmediately
property.- AdvanceImmediately
Boolean value that can be used to overwrite the current value of
Performance
and force the emulation to execute as fast as possible.
There are also some read-only properties that can be used to monitor the current state of the source:
- CurrentLoad
Floating-point value indicating the stress the emulation puts on a host CPU.
Value of 1.0 (the maximal possible) means that the host uses all its CPU resources to run the current emulation and it is not possible to execute it faster. In other words, increasing Performance will not have any effect.
Value of 0.5 means that the host is loaded only in 50% so it is possible to speed up the emulation by a factor of 2.
This value is calculated as an avarage of 10 samples.
- CummulativeLoad
The same as
Load
but calculated as an average over all samples since the beginning of the emulation.- ElapsedVirtualTime
The amount of virtual time that passed since the source has been started.
- NearestSyncPoint
The time stamp of the nearest synchronization phase.
- NumberOfSyncPoints
The number of synchronization phases executed so far.
CPU pausing vs. halting
When any of the members of time domain pauses its execution, it will effectively block virtual time from passing. As a result, all other members will execute to the nearest synchronization phase and wait for the paused member to continue.
Sometimes it is convinient to have a member in the domain that is disabled, but does not block others - e.g., a CPU that is not clocked in multi-CPU architectures.
The CPU class provides the IsHalted
property that allows to achieve this goal.