Overlapping Communication with Computation in MPI Applications