Skip to content

Commit

Permalink
Revised the scheduler examples.
Browse files Browse the repository at this point in the history
  • Loading branch information
baochunli committed Dec 26, 2023
1 parent c46ae41 commit abcb7eb
Show file tree
Hide file tree
Showing 7 changed files with 180 additions and 203 deletions.
20 changes: 6 additions & 14 deletions examples/static_priority.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,36 +11,28 @@


def arrival_1():
""" Packets arrive with a constant interval of 1.5 seconds. """
"""Packets arrive with a constant interval of 1.5 seconds."""
return 1.5


def arrival_2():
""" Packets arrive with a constant interval of 2.0 seconds. """
"""Packets arrive with a constant interval of 2.0 seconds."""
return 2.0


def packet_size():
return 100
return 1000


env = simpy.Environment()
sp1 = SPServer(env,
100, {
0: 1,
1: 10
},
zero_downstream_buffer=True,
debug=True)
sp2 = SPServer(env, 100, {0: 50, 1: 100}, zero_buffer=True, debug=True)
ps = PacketSink(env, rec_flow_ids=False, debug=True)
sp1 = SPServer(env, 8000, {0: 1, 1: 2}, debug=True)
ps = PacketSink(env, debug=True)

pg1 = DistPacketGenerator(env, "flow_1", arrival_1, packet_size, flow_id=0)
pg2 = DistPacketGenerator(env, "flow_2", arrival_2, packet_size, flow_id=1)

pg1.out = sp1
pg2.out = sp1
sp1.out = sp2
sp2.out = ps
sp1.out = ps

env.run(until=20)
61 changes: 18 additions & 43 deletions examples/virtual_clock.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,30 +22,21 @@ def const_size():


env = simpy.Environment()
pg1 = DistPacketGenerator(env,
"flow_0",
packet_arrival,
const_size,
initial_delay=0.0,
finish=50,
flow_id=0)
pg2 = DistPacketGenerator(env,
"flow_1",
packet_arrival,
const_size,
initial_delay=10.0,
finish=50,
flow_id=1)
pg1 = DistPacketGenerator(
env, "flow_0", packet_arrival, const_size, initial_delay=0.0, finish=50, flow_id=0
)
pg2 = DistPacketGenerator(
env, "flow_1", packet_arrival, const_size, initial_delay=10.0, finish=50, flow_id=1
)
ps = PacketSink(env)
sink_1 = PacketSink(env)
sink_2 = PacketSink(env)

source_rate = 8.0 * const_size() / packet_arrival()
source_rate = 4600.0
vc_server = VirtualClockServer(env, source_rate, [2, 1], debug=True)
monitor = ServerMonitor(env,
vc_server,
partial(expovariate, 0.1),
pkt_in_service_included=True)
monitor = ServerMonitor(
env, vc_server, partial(expovariate, 0.1), pkt_in_service_included=True
)
splitter_1 = Splitter()
splitter_2 = Splitter()

Expand All @@ -61,19 +52,13 @@ def const_size():

env.run(until=1000)

print(
"At the Virtual Clock server, the queue lengths in # packets for flow 0 are:"
)
print("At the Virtual Clock server, the queue lengths in # packets for flow 0 are:")
print(monitor.sizes[0])
print(
"At the Virtual Clock server, the queue lengths in # packets for flow 1 are:"
)
print("At the Virtual Clock server, the queue lengths in # packets for flow 1 are:")
print(monitor.sizes[1])
print(
"At the Virtual Clock server, the queue lengths in bytes for flow 0 are:")
print("At the Virtual Clock server, the queue lengths in bytes for flow 0 are:")
print(monitor.byte_sizes[0])
print(
"At the Virtual Clock server, the queue lengths in bytes for flow 1 are:")
print("At the Virtual Clock server, the queue lengths in bytes for flow 1 are:")
print(monitor.byte_sizes[1])

print("At the packet sink, packet arrival times for flow 0 are:")
Expand All @@ -83,26 +68,16 @@ def const_size():
print(ps.arrivals[1])

fig, (ax1, ax2) = plt.subplots(nrows=2, ncols=1, sharex=True)
ax1.vlines(sink_1.arrivals[0],
0.0,
1.0,
colors="g",
linewidth=2.0,
label='Flow 0')
ax1.vlines(sink_2.arrivals[1],
0.0,
0.7,
colors="r",
linewidth=2.0,
label='Flow 1')
ax1.vlines(sink_1.arrivals[0], 0.0, 1.0, colors="g", linewidth=2.0, label="Flow 0")
ax1.vlines(sink_2.arrivals[1], 0.0, 0.7, colors="r", linewidth=2.0, label="Flow 1")
ax1.set_title("Arrival times at the VC server")
ax1.set_ylim([0, 1.5])
ax1.set_xlim([0, max(sink_1.arrivals[0]) + 10])
ax1.grid(True)
ax1.legend()

ax2.vlines(ps.arrivals[0], 0.0, 1.0, colors="g", linewidth=2.0, label='Flow 0')
ax2.vlines(ps.arrivals[1], 0.0, 0.7, colors="r", linewidth=2.0, label='Flow 1')
ax2.vlines(ps.arrivals[0], 0.0, 1.0, colors="g", linewidth=2.0, label="Flow 0")
ax2.vlines(ps.arrivals[1], 0.0, 0.7, colors="r", linewidth=2.0, label="Flow 1")
ax2.set_title("Departure times from the VC server")
ax2.set_xlabel("time")
ax2.set_ylim([0, 1.5])
Expand Down
51 changes: 17 additions & 34 deletions examples/wfq.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,30 +22,21 @@ def const_size():


env = simpy.Environment()
pg1 = DistPacketGenerator(env,
"flow_0",
packet_arrival,
const_size,
initial_delay=0.0,
finish=50,
flow_id=0)
pg2 = DistPacketGenerator(env,
"flow_1",
packet_arrival,
const_size,
initial_delay=10.0,
finish=50,
flow_id=1)
pg1 = DistPacketGenerator(
env, "flow_0", packet_arrival, const_size, initial_delay=0.0, finish=50, flow_id=0
)
pg2 = DistPacketGenerator(
env, "flow_1", packet_arrival, const_size, initial_delay=10.0, finish=50, flow_id=1
)
ps = PacketSink(env)
sink_1 = PacketSink(env)
sink_2 = PacketSink(env)

source_rate = 8.0 * const_size() / packet_arrival()
wfq_server = WFQServer(env, source_rate, [1, 2])
monitor = ServerMonitor(env,
wfq_server,
partial(expovariate, 0.1),
pkt_in_service_included=True)
source_rate = 4600
wfq_server = WFQServer(env, source_rate, [1, 2], debug=True)
monitor = ServerMonitor(
env, wfq_server, partial(expovariate, 0.1), pkt_in_service_included=True
)
splitter_1 = Splitter()
splitter_2 = Splitter()

Expand All @@ -70,33 +61,25 @@ def const_size():
print("At the WFQ server, the queue lengths in bytes for flow 1 are:")
print(monitor.byte_sizes[1])

print(sink_1.arrivals[0])
print(sink_2.arrivals[1])
print("At the packet sink, packet arrival times for flow 0 are:")
print(ps.arrivals[0])

print("At the packet sink, packet arrival times for flow 1 are:")
print(ps.arrivals[1])

fig, (ax1, ax2) = plt.subplots(nrows=2, ncols=1, sharex=True)
ax1.vlines(sink_1.arrivals[0],
0.0,
1.0,
colors="g",
linewidth=2.0,
label='Flow 0')
ax1.vlines(sink_2.arrivals[1],
0.0,
0.7,
colors="r",
linewidth=2.0,
label='Flow 1')
ax1.vlines(sink_1.arrivals[0], 0.0, 1.0, colors="g", linewidth=2.0, label="Flow 0")
ax1.vlines(sink_2.arrivals[1], 0.0, 0.7, colors="r", linewidth=2.0, label="Flow 1")
ax1.set_title("Arrival times at the WFQ server")
ax1.set_ylim([0, 1.5])
ax1.set_xlim([0, max(sink_1.arrivals[0]) + 10])
ax1.grid(True)
ax1.legend()

ax2.vlines(ps.arrivals[0], 0.0, 1.0, colors="g", linewidth=2.0, label='Flow 0')
ax2.vlines(ps.arrivals[1], 0.0, 0.7, colors="r", linewidth=2.0, label='Flow 1')
ax2.vlines(ps.arrivals[0], 0.0, 1.0, colors="g", linewidth=2.0, label="Flow 0")
ax2.vlines(ps.arrivals[1], 0.0, 0.7, colors="r", linewidth=2.0, label="Flow 1")
ax2.set_title("Departure times from the WFQ server")
ax2.set_xlabel("time")
ax2.set_ylim([0, 1.5])
Expand Down
79 changes: 43 additions & 36 deletions ns/packet/dist_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,36 +9,39 @@


class DistPacketGenerator:
""" Generates packets with a given inter-arrival time distribution.
"""Generates packets with a given inter-arrival time distribution.
Parameters
----------
env: simpy.Environment
The simulation environment.
element_id: str
the ID of this element.
arrival_dist: function
A no-parameter function that returns the successive inter-arrival times of
the packets.
size_dist: function
A no-parameter function that returns the successive sizes of the packets.
initial_delay: number
Starts generation after an initial delay. Defaults to 0.
finish: number
Stops generation at the finish time. Defaults to infinite.
rec_flow: bool
Are we recording the statistics of packets generated?
Parameters
----------
env: simpy.Environment
The simulation environment.
element_id: str
the ID of this element.
arrival_dist: function
A no-parameter function that returns the successive inter-arrival times of
the packets.
size_dist: function
A no-parameter function that returns the successive sizes of the packets.
initial_delay: number
Starts generation after an initial delay. Defaults to 0.
finish: number
Stops generation at the finish time. Defaults to infinite.
rec_flow: bool
Are we recording the statistics of packets generated?
"""
def __init__(self,
env,
element_id,
arrival_dist,
size_dist,
initial_delay=0,
finish=float("inf"),
flow_id=0,
rec_flow=False,
debug=False):

def __init__(
self,
env,
element_id,
arrival_dist,
size_dist,
initial_delay=0,
finish=float("inf"),
flow_id=0,
rec_flow=False,
debug=False,
):
self.element_id = element_id
self.env = env
self.arrival_dist = arrival_dist
Expand All @@ -59,22 +62,26 @@ def run(self):
"""The generator function used in simulations."""
yield self.env.timeout(self.initial_delay)
while self.env.now < self.finish:
packet = Packet(
self.env.now,
self.size_dist(),
self.packets_sent,
src=self.element_id,
flow_id=self.flow_id,
)

# wait for next transmission
yield self.env.timeout(self.arrival_dist())
self.out.put(packet)

self.packets_sent += 1
packet = Packet(self.env.now,
self.size_dist(),
self.packets_sent,
src=self.element_id,
flow_id=self.flow_id)

if self.rec_flow:
self.time_rec.append(packet.time)
self.size_rec.append(packet.size)

if self.debug:
print(
f"Sent packet {packet.packet_id} with flow_id {packet.flow_id} at "
f"time {self.env.now}.")

self.out.put(packet)
f"time {self.env.now}."
)
40 changes: 23 additions & 17 deletions ns/packet/sink.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@


class PacketSink:
""" A PacketSink is designed to record both arrival times and waiting times from the incoming
"""A PacketSink is designed to record both arrival times and waiting times from the incoming
packets. By default, it records absolute arrival times, but it can also be initialized to record
inter-arrival times.
Expand All @@ -33,13 +33,15 @@ class PacketSink:
If True, prints more verbose debug information.
"""

def __init__(self,
env,
rec_arrivals: bool = True,
absolute_arrivals: bool = True,
rec_waits: bool = True,
rec_flow_ids: bool = True,
debug: bool = False):
def __init__(
self,
env,
rec_arrivals: bool = True,
absolute_arrivals: bool = True,
rec_waits: bool = True,
rec_flow_ids: bool = True,
debug: bool = False,
):
self.store = simpy.Store(env)
self.env = env
self.rec_waits = rec_waits
Expand All @@ -61,7 +63,7 @@ def __init__(self,
self.debug = debug

def put(self, packet):
""" Sends a packet to this element. """
"""Sends a packet to this element."""
now = self.env.now

if self.rec_flow_ids:
Expand All @@ -82,22 +84,26 @@ def put(self, packet):
self.first_arrival[rec_index] = now

if not self.absolute_arrivals:
self.arrivals[rec_index][
-1] = now - self.last_arrival[rec_index]
self.arrivals[rec_index][-1] = now - self.last_arrival[rec_index]

self.last_arrival[rec_index] = now

if self.debug:
print("At time {:.2f}, packet {:d} {:d} arrived.".format(
now, packet.packet_id, packet.flow_id))
print(
"At time {:.2f}, packet {:d} in flow {:d} arrived.".format(
now, packet.packet_id, packet.flow_id
)
)
if self.rec_waits and len(self.packet_sizes[rec_index]) >= 10:
bytes_received = sum(self.packet_sizes[rec_index][-9:])
time_elapsed = self.env.now - (
self.packet_times[rec_index][-10] +
self.waits[rec_index][-10])
self.packet_times[rec_index][-10] + self.waits[rec_index][-10]
)
print(
"Average throughput (last 10 packets): {:.2f} bytes/second."
.format(float(bytes_received) / time_elapsed))
"Average throughput (last 10 packets): {:.2f} bytes/second.".format(
float(bytes_received) / time_elapsed
)
)

self.packets_received[rec_index] += 1
self.bytes_received[rec_index] += packet.size
Loading

0 comments on commit abcb7eb

Please sign in to comment.