![]() |
Faculty of Engineering and Information Technology (FEIT)
Department of Computer Science
|
COMP2310 Assignment 2: Distributed Merge SortDeadline: 23:57 Friday 19 October 2007
Late Penalty: Submission DetailsYou are required to submit the files mergepipe.c, mergesocket.c, mergethread.c, and write-up.txt for the assignment name Ass2. The following command can be used to perform this:
Some notes:
IntroductionMany algorithms requiring substantial computational resources have a tree-like structure (i.e. use a divide-and -conquer strategy). These can normally adapted to a distributed computation, and especially the case if the tree can be kept balanced (i.e. use p=2k processors by assigning p/2 processes to the left sub-tree and p/2 to the right sub-tree). Merge sort is an example of this.In this assignment you will implement various forms of a distributed merge sort using various IPC and shared memory features of Unix and the C programming language. The figure below depicts the structure of a distributed merge sort with p = 8 processes. The tree indicates the process structure, beginning with process 0 at the top-level (d = 0). However, instead of spawning 2 child processes, it only spawns 1 for the right sub-tree, and then it processes the left sub-tree itself. This continues recursively for k = log2(p) levels, at which point p processes have been created. These processes sort their respective segment of the array. Then, the tree structure is traversed upwards, with the respective process at each node then merging the array segment from its right child into its own segment from the next level down. In this step the right child may have to explicitly communicate its array segment; then that process is free to terminate. As the tree traversal return to level d = 0, process 0 performs the final merge and the array is sorted.
It is assumed that p is a power of 2, with p>=1 and
n>=0. The numbering of the process id's shown in the figure is
only one of several possibilities; however, it can be seen that the
binary representation of process id i can be used to determine
what each process should do at each step. For example, at level
d (0 <= d < k), if the dth bit (where the 0th
bit is the least significant bit) of i is one, process
i is currently the right child in the sub-tree (this can be
encoded in C as ((i & (1 << d)) != 0), for those that missed
COMP2300, or have otherwise forgotten:). Also, by reversing the order
of the bits in i, the offset of the array segment at level
The directory /dept/dcs/comp2310/public/ass2 contains template
files for the files that you will submit. It also contains a library of
provided functions in mergelib.h and mergelib.c. It also
contains a Makefile which should be used to compile the
programs (note the use of the -Wall and -lmcheck) on
both Linux and Solaris systems. Copy these files into your local
directory area before you begin work on your programs.
The original (parent) process processes the command line parameters (any
errors should result in an appropriate error message being given, and
the process exiting with a status of 1), allocates via malloc()
an array A of size n (and any other buffers it needs),
and invokes the provided external function genArray(A, n, s)
to initialize the array A. If the printing option was
specified, it should call the provided function printArray(A,
n). Then startSortTimer() should be called.
The distributed merge sort is then performed, which involves the (direct
or indirect) forking of a further p-1 processes. The array
segments should be transferred between processes using Unix pipes. Note
that the semantics of fork() can be utilized to reduce the
amount of explicit data transfer. The provided external function
mergeSort(int A[], int tmp[], int n) can be used to sort a
segment of A[0:n-1] (using tmp[0:n-1] as temporary
storage), and merge(int A[], int L[], int nL, int R[], int nR) can be
used to merge L[0:nL-1] and R[0:nR-1] into
A[0:nL+nR-1]. The standard C function bcopy() can be used
to copy array segments, if needed.
For full marks, no process should contain more than k copies of
pipe descriptor pairs, and processes should close any pipe as soon as no
longer needed. Child processes should exit when their participation in
the sort is finished, and their parent should wait on them to do this.
When the sort is completed, the original (parent) process calls
stopSortTimer(), printArray(A, n) if the printing
option was specified, and then checkArray(A, n, s), where
A[0:n-1] should now hold the sorted array.
Debugging: the use of printf("%d:...\n", i, ...)
statements, where i is the process or thread id, at strategic
points is recommended. printArray() can be used to print out
array segments. Noting that your program(s) should not produce any
output directly, you should remove these and any other print statements
before submitting. Running your program under strace -f may
also be helpful for debugging (called truss -f on
iwaki - the output on Solaris is more readable, so it may be
preferable to use that).
Warning: clean up the common code in mergepipe.c
before you copy it!
Hint: it is recommended that you pass the logical thread id
(as in the above diagram) as the parameter of the function that the
threads execute. The use of shared memory may call for a substantially
different program structure! And remember, the easiest ways to the
threads to access data they may need to share (e.g. the array length and
the array itself) is through global variables.
In the file write-up.txt, answer the following questions.
Which version is fastest? Explain whether this what you expect, given
your knowledge of the underlying mechanisms used. The theoretical
maximum speedup for the p=4 timings over the p=1
timing is 4. Are you observing close to this speedup? Explain why this
might be the case (Hint:try doubling (or more) n; does
the speedup improve significantly?)
|
|
Please direct all enquiries to: Alistair.Rendell@anu.edu.au Page authorised by: Head of Department, DCS |
| The Australian National University — CRICOS Provider Number 00120C |