• 沒有找到結果。

Simulation Engine Modification

3 Design and Implementation

3.2 Simulation Engine Modification

This section describes the modification of the NCTUns simulation engine for the parallel discrete event simulation. The operations of the kernel in the parallel simulation mode are different from those in the single machine mode, so a simulation

engine needs a way to make kernel know in which mode it has to run. We achieve this by altering two system calls shown in Figure 3-3.

syscall(275, 0x0c, 0, 0, 0); // Let kernel node S.E. are in parallel/distributed mode.

syscall(275, 0x0d, 0, 0, 0); // Reset the parameter “parallel_mode”.

Figure 3-3 The hacked system call to set parallel/single mode in kernel.

The detail of a simulation executed on a single machine is explained on [27]. The basic idea is shown in Figure 3-4. The TCP/IP protocol stack used in the simulation is an existing real-life one in the kernel. Although each node thinks that it has its own protocol stack, all simulated nodes actually have the same protocol stack because they are all run on a single machine. The tunnel interfaces shown in the Figure are pseudo network interfaces that do not have a real physical network attached to it. However, from the kernel’s point of view a tunnel interface is not different from any real Ethernet network interfaces.

In Figure 3-4, the TCP sender sends a packet into the kernel, and the packet goes through the kernel’s TCP/IP protocol stack just as an Ethernet packet would do.

Because we configure the tunnel interface 1 as the packet’s output device, the packet will be inserted to tunnel interface 1’s output queue. The simulation engine will immediately detect such an event and issue a read system call to get this packet through tunnel interface 1’s special file (Every tunnel interface has a corresponding device special file in the /dev directory.). After experiencing the simulation of transmission delay and link’s propagation delay, the simulation engine will issue a write system call to put the packet into tunnel interface 2’s input queue. The kernel will then raise a software interrupt and put the packet into the TCP/IP protocol stack.

Then, the packet will be put into the receive queue of the socket that the TCP receiver creates. Finally, the TCP receiver will use a read system call to get packet out of the kernel.

Figure 3-4 The original kernel re-entering simulation methodology.

In Figure 3-5, we illustrate how several parallel/distributed simulation engines cooperate to complete a simulation. The simulation engines A and B have the same information for the simulated network, but each of both only simulates a portion of the network. The TCP sender is simulated on the simulation engine A, and the TCP receiver is simulated on the simulation engine B. As illustrated in Figure 3-4, when a packet is sent out from the TCP sender, it will be captured by the simulation engine A before it is inserted into the simulation engine’s event list. The simulation engine A first checks if the destination node of this packet is simulated is a local simulated node or a remote simulated node. The simulation engine A regards a simulated node as a local node if this node is simulated on the simulate engine A itself. Otherwise, the simulation engine A regards a simulated node as a remote node. Next, the simulation

engine A obtains the node ID of the destination node for this remote packet via the

“get_nid()” NCTUns API call. The “get_nid()” NCTUns API call is a primitive function call provided by the simulation engine. This function call works well in our parallel simulation environment because, as mentioned previously, each simulation engine creates all simulated nodes with at least necessary data structures and thus the node list of each simulation engine includes the information for all simulated nodes.

As such, even if the “get_nid()” call is for a remote node, it still succeed in returning the correct node ID for that remote node.

Figure 3-5 The parallel simulation methodology.

Then, the simulation engine looks up the “parallel.cfg” file to know which remote simulation engine is responsible for the simulation of the destination node.

Afterwards, the simulation engine A encapsulates this simulated packet into a specific event format defined in the “parallel.h” header file and passes the encapsulated event to the simulation engine B through the underlying real network. The simulation engine B inserts this remote event into its own event list upon its receiving this remote

event. Finally, the TCP receiver on the machine of the simulation engine B will receive this simulated packet sent from the TCP sender on the machine of A.

User-level traffic generators are executed on top of a simulation engine. A simulation engine is not allowed to execute traffic generators belonging to non-local nodes to make sure the behaviors of user-level application programs are correct. We achieve this by modifying the “read_trafficGen()” function in the “event.cc” file.

int scheduler::executeEvent() {

do {

if (need the synchronization computation)

parallel_->syn(); // Performs the synchronization computation if (at least one safe event)

process the safe event // process the safe event } while (simulation is not over)

}

Figure 3-6 A pseudo code for parallel mechanism.

In the parallel simulation, all simulation engines repeatedly cycles of two phases,

“synchronization” and “event processing”. We modified the “scheduler” component, defined in the “scheduler.cc” file, in the simulation engine based on the pseudo code shown in Figure 3-6. In the synchronization phase, a simulation engine gets the value of EIT. In the event processing phase, a simulation engine is allowed to process the safe events, the timestamps of which are before EIT.

相關文件