Deadlines
lab5.py
-- check-in code for Lab #5
lab5_wnet.py
-- WirelessNetwork and related classes
lab5_wnode.py
-- WirelessNode and related classes
lab5_util.py
-- WSim utilities (Packet, Stats classes)
lab5_1.py
-- template file for Task #1 (TDMA)
lab5_2.py
-- template file for Task #2 (Aloha with fixed sending prob)
lab5_3.py
-- template file for Task #3
(Stabilizing Aloha with backoffs)
lab5_4.py
-- template file for Task #4 (CSMA)
lab5_5.py
-- template file for Task #5 (CSMA
with contention windows)
lab5.zip
-- compressed archive of all these files
Complete the tasks below, submit your task files on-line before the deadline, and sign-up for your check-off interview with your TA.
As always, help is available in 32-083 (see the Lab Hours web page).
For this lab, if you would like to use the GUI to help in debugging, you will need wxPython (2.8.x), which has already been installed on the athena machines. To install it on your computer, visit http://www.wxpython.org/
Three files -- lab5_wnet.py, lab5_wnode.py, and lab5_util.py -- implement the bulk of WSim. You won't need to modify these files for tthis lab. The five lab task files (lab5_n.py) contain the classes and methods that you will need to work on.
You can run the python programs for this lab using ipython or python (ipython602 and python602 on the athena machines). This lab does not work well in IDLE (you can use IDLE to edit files, but running them may not work as expected).
To understand the different parameters one can set in WSim, go to a shell (i.e., command line prompt) and enter:
python602 lab5_1.py -h
(Or, in ipython, run lab5_1.py -h)
This command prints out the various options; the important ones are:
WSim runs for a specified number of time slots (settable using the -t option, with a default of 10000) and prints out some performance numbers (and possibly displays some graphs) at the end. Of interest to us are the utilization and fairness numbers, which are defined in the lecture notes (L10-11). The code reports a "weighted" fairness number as well, which is the fairness index calculated over the ratio of the observed throughputs to offered loads. The (unweighted) inter-node fairness is calculated over the throughputs alone, without regard to the offered load.
In this lab, you will implement the core of three MAC protocols---TDMA, stabilized Aloha (with backoffs), and CSMA---and understand their performance. Each node is an object, which has three methods that you can use to implement the core of the MAC protocol:
You can modify any per-node state that you want to in these methods (e.g., the state maintained by the backoff scheme, statistics of interest, etc.). Make sure to add the code to initialize this state in the Node object's __init__ function, whose body is included in the lab task files.
In many of our experiments, we will use the -r option, which cause the nodes to retry upon experiencing a collision. (Of course, the MAC protocol's channel_access() method will determine when the retry actually occurs.)
Implement a simple TDMA scheme by suitably filling in the channel_access() method in the template file lab5_1.py. Recall that in a TDMA scheme, time is divided into numnodes equal-size slots, each long enough to accommodate the transmission of a single packet and that each node is allocated one of the slots to use when it has a packet to transmit. Note that a node can determine its unique node number (an integer between 0 and numnodes-1) by calling self.get_id().
The slightly tricky part of this function is to correctly handle packet sizes that are larger than 1 time slot. We want the TDMA scheme to treat each packet as an atomic unit of transmission; when the protocol determines that a given node can send, that node should send the complete packet. Put another way, we want the effective size of a time slot in the scheme to be equal to the packet size. You will probably find it easier to first write the function and run it for a packet size of 1 slot, then modify your code to correctly handle larger packet sizes. Note that when the packet size is set to some value using the -s option, all nodes will use that value.
Run the following using python602 or ipython602 (after you test it for various packet sizes to ensure that there are no collisions):
When you're ready to submit your code on-line, enable the call to lab5.checkoff. This will just upload your file to the server. When submitting, run your task file using python602 since the submission will not work correctly when run from idle602.
Please enter your answers to the following questions on-line on the lab questions page.
1.1: With a skewed load (-k), as one increases the number of nodes, what happens to the utilization? Why?
1.2: What is the number of nodes at which the network utilization is smaller than 0.25 for the skewed workload? (Because each run is randomized, run it a few times to be confident of your answer.)
In this task, we will implement slotted Aloha with a fixed transmission probability and measure its performance under different conditions. The program allows you to set the transmission probability using the -p option. Looking at lab5_2.py, note that the __init__ function of AlohaWirelessNetwork sets each node's "p" to the configured value of the transmission probability. Your task is to implement the Aloha MAC protocol by providing the correct code in channel_access(), so that the node will transmit packets with the configured probability. Your scheme should work when a packet is 1 slot long, but also for longer packet sizes (of course, the utilization may be different for different packet sizes).
Please note: For this task as well as the subsequent ones, do not use numnodes in your code, even though it is accessible. The reason is that we want your algorithm to work for arbitrarily distributed offered loads, and using numnodes will not help achieve that.
Test your code by running the following for different values of p and observe the resulting utilization. These tests use the -r option to force multiple nodes to usually be backlogged. With this option, each collision causes a retry. Because the (default) offered load is 100%, the retries ensure that the total offered load exceeds the channel rate. You can also observe this backlog if you run the following tests with the -g option and pay attention to the queue lengths at the nodes.
python602 lab5_2.py -n 16 -r -p PROBABILITY_HERE
When you're ready to submit your code on-line, enable the call to lab5.checkoff. This will just upload your file to the server. When submitting, run your task file using python602 since the submission will not work correctly when run from idle602.
Please enter your answers to the following questions on-line on the lab questions page.
2.1: What value of p in the range (0,1) maximizes the utilization in your experiments? What is the maximum utilization?
2.2: We will now explore a skewed load to see whether that affects the best choice of p. Run the following for a few values of p.
python602 lab5_2.py -n 16 -r -k -p PROBABILITY_HERE
What value(s) of p in the range (0,1) maximizes the utilization in your experiments in this case? What is the maximum utilization?
2.3: How do the optimal values of p and the corresponding utilization compare with the no-skew case? Why are they different?
We will use two parameters, pmax and pmin. These correspond to the maximum and minimum values of the transmission attempt probability, p. The values of these parameters can be set from the command line when you run the program, and are available as self.network.pmax and self.network.pmin respectively (see the __init__ function of AlohaWirelessNetwork). In your code, ensure that pmin ≤ p ≤ pmax.
You can use any algorithm you want to set p in these functions, including the ones discussed in lecture. Good schemes achieve high utilization, but ensure also that fairness is high (as close to 1 as possible -- lower than 0.9 is a sign that there is significant unfairness when the number of nodes is between 8 and 16) and avoid the capture effect. There is no absolute correct answer (though there are bad methods!), so feel free to be creative if you think you have a good idea. Note that you are not allowed to use the number of backlogged nodes in your scheme, because that information would not be available in practice.
In the on_collision function, if you add the line self.coll.append(self.network.time) and in the on_xmit_success() function, if you add the line self.sent.append(self.network.time), you'll be able to see a plot of the red and blue points corresponding to collisions and successful packets, respectively. Remember to initialize each list to [] in __init__().
Run your code as follows for a few different settings of pmin and pmax and observe the utilization and inter-node fairness values.
python602 lab5_3.py -r -n 8 --pmax=PROBABILITY_HERE --pmin=PROBABILITY_HERE
(Note the two dashes in front of the pmax and pmin options.)
When you're ready to submit your code on-line, enable the call to lab5.checkoff. This will just upload your file to the server. When submitting, run your task file using python602 since the submission will not work correctly when run from idle602.
Please enter your answers to the following questions on-line on the lab questions page.
3.1: Run python602 lab5_3.py -r -n 8 --pmin=0 --pmax=1. Would you recommend running a real network with these parameters for pmin and pmax? Briefly explain your answer.
3.2: Pick pmin and pmax so that the fairness is as large as possible when the number of nodes is 8 and there is no load skew. What is the utilization of your protocol when the packet size is 10 slots? How does it compare to the utilization when the packet size is 1?
For the first case (packet size of 10), run
python602 lab5_3.py -s 10 -t 70000 -r -n 8
--pmax=PROBABILITY_HERE --pmin=PROBABILITY_HERE
For the second case (packet size of 1), run
python602 lab5_3.py -r -n 8
--pmax=PROBABILITY_HERE --pmin=PROBABILITY_HERE
In this task, we will try to get the best utilization and fairness we can for a MAC protocol that uses CSMA. To check if the channel is idle, you can use the self.network.channel_idle() from inside channel_access(). This function returns True if there is no on-going transmission in the current time slot, and False otherwise.
Every carrier sensing mechanism has a detection time, defined as the time interval between the ending of a previous transmission and the detection of the channel as "idle" by a node. For the purposes of this lab, we will assume that the detection time is 0. Hence, a node can sense that the carrier is idle in the immediate next slot after the termination of the previous transmission, when it does the check for whether the channel is busy. However, it is still possible for collisions to occur, for multiple nodes could simultaneously sense the channel at the beginning of a slot, and conclude that the channel is "idle", and possibly attempt a transmission in that time slot (or in the same future time slot).
Write your code lab5_4.py for the channel_access() method assuming that the node has the ability to sense the carrier. Obviously, you should fill in the steps for the on_collision() and on_xmit_success() methods as well.
In the on_collision function, if you add the line self.coll.append(self.network.time) and in the on_xmit_success() function, if you add the line self.sent.append(self.network.time), you'll be able to see a plot of the red and blue points corresponding to collisions and successful packets, respectively. Remember to initialize each list to [] in __init__().
Test your code as follows. The -s option is important because it causes the packets to be longer than 1 slot, allowing a node to sense whether another transmission is in progress during a time slot.
python602 lab5_4.py -r -n 8 -s 10 -t 100000 --pmax=PROBABILITY_HERE --pmin=PROBABILITY_HERE
Note that you should run the above for 100000 time slots, because we have scaled up the packet size to 10 (from 1).
When you're ready to submit your code on-line, enable the call to lab5.checkoff. This will just upload your file to the server. When submitting, run your task file using python602 since the submission will not work correctly when run from idle602.
Please enter your answers to the following questions on-line on the lab questions page.
4.1: What is the utilization and fairness of your protocol when pmin = 0 and pmax = 1?
4.2: How would you set pmin and pmax in your protocol to make the fairness number be over 0.95 consistently?
The ALOHA and CSMA schemes in the previous tasks pick a probability p for transmitting a packet, and adapt p to stabilize the protocol. The advantage of this method is that it is easy to analyze. In practice, however, real-world CSMA protocols like the popular 802.11 WiFi standard and the 802.3 Ethernet standard implement something a bit different, as explained below. Your task will be to write the code for the key parts of this scheme.
Rather than decide whether any given slot should have a transmission with probability p, each node maintains a contention window, which we denote by cw. cw is initially set to cwmin, which is a small positive integer (say, 1). Denote the current time slot by C. If the sender is backlogged, it picks a random integer t in [1, cw] and decides to send a packet in time slot C + t.
Of course, with carrier sense in place, the sender should only send a packet if the channel is idle in time slot C + t. So, the sender senses the carrier in that time slot, and then sends a packet only if the channel is idle then. If the channel is not idle, it waits until the channel is idle, and then sends the packet.
Whenever a collision occurs, the node doubles cw, but makes sure cw never exceeds cwmax (say, 512). Whenever a transmission is successful, the node might reset cw to cwmin, or might halve its current value of cw. You will note that this scheme is similar in spirit to the probabilistic transmission scheme from Task #4, but a crucial difference is that here each backlogged node is guaranteed to send a packet within a finite time, unlike in the probabilistic case where there is always a small probability that the node cannot send within any given number of time slots. In mathematical terms, the probability distribution that governs whether a node transmits a packet in a given time slot is uniform in this scheme (Task #5), while it is geometrically distributed in the previous case (Task #4).
You will first implement the scheme described thus far. It will turn out not to do as well as we would like, and in Task 5.2, you will fix an important weakness.
Implement this scheme by writing the appropriate code for
channel_access(), on_collision(), and on_xmit_success()
in lab5_5.py.
How well does it work? To answer
this question, measure the utilization and fairness by running
python602 lab5_5.py -r -s 10 -n 8 -t 100000
-W 256
The -W option sets the maximum contention window size. The minimum contention window is 1 (you can change it using the -w option if you like (lower case "w"). Running the above, you will note that even with carrier sense being used, the utilization is quite a bit lower than in Task 4.
Please enter your answers to the following questions on-line on the lab questions page.
5.1: Report the utilization and fairness. Briefly explain why
the utilization is low.
Hint: Think about what happens if more than one node is backlogged and
waiting for an on-going transmission to complete; what happens when
the on-going one finishes?
To fix this problem, each node needs to ignore the time slots when other nodes are transmitting data. That is, if a node picks a time slot t in [1, cw] to transmit, it should wait for that many idle slots before attempting its own transmission. Of course, before transmitting data, it should ensure that the channel is idle.
5.2: Modify your code to include the above
suggestion and run the same command as before:
python602 lab5_5.py -r -s 10 -n 8 -t 100000
-W 256
Report the utilization and fairness for your scheme after including the suggestion and running the same command as before.