inputs: a(n,n)
outputs: π(n), l(n,n), and u(n,n)
initialize π as a vector of length n
initialize u as an n x n matrix with 0s below the diagonal
initialize l as an n x n matrix with 1s on the diagonal and 0s above the diagonal
for i = 1 to n
π[i] = i
for k = 1 to n
max = 0
for i = k to n
if max < |a(i,k)|
max = |a(i,k)|
k' = i
if max == 0
error (singular matrix)
swap π[k] and π[k']
swap a(k,:) and a(k',:)
swap l(k,1:k-1) and l(k',1:k-1)
u(k,k) = a(k,k)
for i = k+1 to n
l(i,k) = a(i,k)/u(k,k)
u(k,i) = a(k,i)
for i = k+1 to n
for j = k+1 to n
a(i,j) = a(i,j) - l(i,k)*u(k,j)
Here, the vector π is a compact representation of a permutation matrix p(n,n),
which is very sparse. For the ith row of p, π(i) stores the column index of
the sole position that contains a 1.
You will write two shared-memory parallel programs that perform LU
decomposition using row pivoting. You will develop one solution using the Pthreads programming model and one using OpenMP.
The verification step need not be parallelized. Have your program time the LU decomposition phase by reading the real-time clock before and after and printing the difference.
The formal components of the assignment are listed below:
Use problem size n = 8000 to evaluate the performance of your implementations. If your sequential running time is too long for the interactive queue, you may base your timing measurements on n=7000. Prepare a table that includes your timing measurements for the LU decomposition phase of your implementations on 1, 2, 4, 8, and 16 threads. Plot graphs of the parallel efficiency of your program executions. Plot a point for each of the executions. The x axis should show the number of processors. The Y axis should show your measured parallel efficiency for the execution. Construct your plot so that the X axis of the graph intersects the Y axis at Y=0.
In this assignment, reading and writing shared data will account for much of the execution cost. Accordingly, you should pay attention to how you lay out the data and how your parallelizations interact with your data layout. You should consider whether you want to use a contiguous layout for the array, or whether you want to represent the array as a vector, of n pointers to n-element data vectors. You should explicitly consider how false sharing might arise and take appropriate steps to minimize its impact on performance.