EECS 489 Lab 8: Weighted Fair Queueing
This assignment is due on Friday,
15 April 2016, 6 pm.
Introduction
One of the main tool to provide resource isolation, either for
performance guarantee or infrastructure virtualization, is fair
queueing (FQ), otherwise known as generalized processing
sharing (GPS). In this lab, we implement a simplified weighted
fair queueing (WFQ) scheduler. The main simplification we make is to
assume that once a flow (or job) has started, the flow never goes
idle. If a flow can go idle, when it resumes service, we would need
to compute the scheduling round at which service is resumed. This
computation is complicated by the arrival and departure of other flows
during this flow's idle time. Everytime a flow arrives or departs, it
stretches or shrinks the duration of a scheduling round by changing
the total allocated resources. Hence to compute the round at which a
flow resumes service we would have to keep track of the changes in
scheduling round during its idle time. This is known as "round
catchup" in the literature. By assuming that a flow doesn't go idle,
we avoid doing "round catchup" in our implementation.
Another assumption we make is that once a packet starts transmission
we do not pre-empt it to serve another newly arriving packet with a
smaller finish time. This assumption implies that we account for
flow arrivals and departures only between packet transmissions.
We continue to build on our UDP-based client-server code. This code
base does not implement flow control, reliable delivery, nor rate
control. As usual, you're provided with a skeleton code and a
reference Linux binary executable of the server--called refwfqdb
in
/afs/umich.edu/class/eecs489/w16/lab8/.
The client is the same one used in Lab7. The implementation of WFQ
requires you to modify only the server code. The provided
Makefile builds netimg and wfqdb. You can
download the
support code and copy the files to your
working folder for Lab7 (you may want to save a copy of your Lab7
Makefile, imgdb.h, and imgdb.cpp before
overwriting them with the ones for this lab). Access to the support
code is available only to students who have turned in PA3 or decided
not to do so. As usual, you can search for
the string "YOUR CODE HERE" in the code to find places where your code
must go. You may also want to consult the lecture notes on WFQ and PA4 walk-through. Your implementation of the server must
interoperate with the provided client.
Recall that the client's -r command-line option is used to
specify the flow's rate, in Kbps. The server in this lab takes three
optional command-line arguments -l, -g, and -f.
The -l argument allows you to specify the server's link rate,
in Mbps, ranging from 1 to 10. The -g argument allows you to
specify the minimum number of flows that must be initiated before
transmission starts. Transmission will not start unless either this
many number of flows have been initiated or if total reserved rate has
reached link capacity. We call this "gated start." Without gated start,
a flow could easily finish transmission before we could start a second one.
The -f option and its associated imgdb::frac member
variable are used in PA4 and will be described in the PA4 spec.
The default values of the command line options can be found in
netimg.h.
Weighted Fair Queueing (WFQ)
Your first task is to complete the code in imgdb::handleqry() to
add a new flow. When a new flow is to be added, first look for an
empty slot in the flow table to hold the flow. Also check that
the link still have enough capacity to serve the flow's reserved rate.
If the new flow cannot be accommodated, send back to the client an
imsg_t packet with im_type set to
NETIMG_EFULL. Otherwise, increment the flow count and total
reserved rate of the scheduler and call Flow::init() to
initialize the flow. This task should take about 10 lines of code.
To send a packet, you first compute the finish time of each flow's
next segment. Complete the 1-line computation for next finish time in
Flow::nextFi() (Task 2). [To avoid unnecessary arithmetic,
we can assume that the finish times computed are multiplied by 128
(1024/8), i.e., the segment size can be in bytes instead of Kbits.]
Then determine, in imgdb::sendpkt(), the flow with the
smallest next finish time and call Flow::sendpkt() on the
flow to send the next packet (Task 3). This task should take about 10
lines of code.
Your last task (Task 4) is to call Flow::done() when the flow
has finished sending, as indicated by the return value of
Flow::sendpkt(). When a flow has finished sending, decrement
the scheduler's flow count and deduct the flow's reserved rate from
the scheduler's total reserved rate. This is a 2-line task for a
total of less than 25 lines of code for this whole lab.
Testing Your Code
Unfortunately you may not always be able to see the effect of the
scheduling order on the displayed images. You would have to rely on
the server's transmission log instead. The code for logging packet
transmission at the server is part of the support code provided to
you. Do not modify this code.
Run wfqdb:
% wfqdb -g 2
which starts the server with the default link rate of 10 Mbps and
gated start set to 2 flows. Then run two instances of netimg
on two different shells/windows:
% netimg -s localhost:<port> -q ShipatSea.tga -r 256
% netimg -s localhost:<port> -q BlueMarble2004-08.tga -m 8192 -r 1024
(The display of the two instances of netimg may be on top of
each other; drag the top image display window aside to view the other
display window.) The two transmissions should complete about the same
time (a few hundred microseconds apart) with the BlueMarble flow
(flow 1) completing before the ShipatSea flow (flow
0). Observing the server's transmission log, you should see that
multiple BlueMarble flow's packets are sent for each ShipatSea
flow's.
After quitting the two instances of netimg (you can leave the
imgdb running), start two new instances of netimg:
% netimg -s localhost:<port> -q ShipatSea.tga -r 128
% netimg -s localhost:<port> -q BlueMarble2004-08.tga -m 8192 -r 128
You should see the BlueMarble flow completing much later (well, by a
millisecond or so) than the ShipatSea flow and that multiple ShipatSea
flow's packets are sent for each BlueMarble flow's.
Submission Instructions
To incorporate publicly available code in your solution, or to pass
off the implementation of an algorithm as that of another are both
considered cheating in this course. If you can not implement a
required algorithm, you must inform the teaching staff when turning in
your assignment.
Your submission must compile and run without errors on CAEN
eecs489 hosts using the provided Makefile, unmodified, without any additional libraries or
compiler options.
Your "Lab8 files" comprises your imgdb.cpp.
To turn in your Lab8, upload a zipped
or gzipped
tarball of your Lab8 files to the CTools Drop Box. Keep your own backup copy! The timestamp on your
uploaded file is your time of submission. If this is past the
deadline, your submission will be considered late. You are allowed
multiple "submissions" without late-policy implications as
long as you respect the deadline. We highly recommend that you use a
private third party repository such as github
or M+Box or Dropbox or Google Drive to keep the back up copy of your
submission. Local timestamps can be easily altered and cannot be used
to establish your files' last modification times (-10 points). Be
careful to use only third-party repository that allows for
private access. To put your code in publicly accessible
third-party repository is an Honor Code
violation.
Turn in ONLY the files you have modified. Do
not turn in support code we provided that you haven't modified (-4 points).
Do not turn in any binary files (object, executable, dll,
library, or image files) with your assignment (-4 points). Your code
must not require other additional libraries or header files other
than the ones listed in the Makefile (-10 points).
Do remove all printf()'s or
cout's and cerr's and any other logging statements
you've added for debugging purposes. You should debug using a
debugger, not with printf()'s. If we can't understand the
output of your code, you will get zero point.