Lab CPD-2
Lab CPD-2
Lab CPD-2
com
Contents
1 Preparation 2
1.1 Eclipse IDE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.2 Getting Started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
2 Concurrent Programming 2
2.1 Threads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
2.2 Liveness . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.2.1 Deadlock . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.2.2 Livelock . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.2.3 Starvation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.3 Isolation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.4 Dining Philosophers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
3 Parallel Programming 11
3.1 Task Parallelism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.2 Functional Parallelism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.2.1 Futures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.2.2 Streams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.3 Loop Parallelism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
4 Distributed Programming 17
4.1 Client-Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
4.1.1 Unicast Communication (one-to-one) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
4.1.1.1 OneServer - OneClient . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
4.1.1.2 OneServer - MultiClients . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
4.1.2 Broadcast Communication (one-to-all) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
4.1.2.1 OneIP - MultiPorts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
4.1.2.2 MultiIPs - OnePort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
4.1.3 Remote Method Invocation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
4.2 Message Passing Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
4.2.1 Getting Started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
4.2.2 Point-to-Point Communication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
4.2.3 Collective Communication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
4.2.4 Reciprocal ArraySum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
5 Exercises 27
5.1 Exercise Deadlock . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
5.2 Exercise Futures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
5.3 Exercise Streams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
5.4 Exercise OneServer - MultiClients . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
5.5 Exercise Remote Method Invocation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
5.6 Exercise Message Passing Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
1 Preparation
1.1 Eclipse IDE
- Download and install the Eclipse IDE (for Java Developers) from: https://www.eclipse.org/downloads/packages/release
• Name: Main
• Which method stubs would you like to create: check ’public static void main(String[] args)’
2 Concurrent Programming
2.1 Threads
- Create ’ThreadsJoin’ project
- Create ’src/MyUtil.java’ file (https://gist.github.com/tsonkk/678479ab009216375b14e2981edd2142)
1 public class MyUtil {
2 static void doSomething ( long millis ) {
3 try {
4 Thread . sleep ( millis ) ;
5 } catch ( I n t erruptedException ex ) {
6 ex . printStackTrace () ;
7 }
8 }
9 }
2.2 Liveness
2.2.1 Deadlock
- Create ’ThreadsDeadlock’ project
- Create ’src/MyUtil.java’ file (https://gist.github.com/tsonkk/0cd021311bdd8f4ee2bb2ccf425fc483)
1 public class MyUtil {
2 static void doSomething ( long millis ) {
3 try {
4 Thread . sleep ( millis ) ;
5 } catch ( I n t erruptedException ex ) {
6 ex . printStackTrace () ;
7 }
8 }
9 }
4
5 public Runner ( Object obj1 , Object obj2 ) {
6 this . obj1 = obj1 ;
7 this . obj2 = obj2 ;
8 }
9 @Override
10 public void run () {
11 run1 () ;
12 }
13 // deadlock
14 private void run1 () {
15 System . out . println ( Thread . currentThread () . getName () + " acquiring lock on " + obj1 ) ;
16 synchronized ( obj1 ) {
17 System . out . println ( Thread . currentThread () . getName () + " acquired lock on " + obj1 ) ;
18 MyUtil . doSomething (3000) ;
19
20 System . out . println ( Thread . currentThread () . getName () + " acquiring lock on " + obj2 ) ;
21 synchronized ( obj2 ) {
22 System . out . println ( Thread . currentThread () . getName () + " acquired lock on " + obj2 ) ;
23 MyUtil . doSomething (5000) ;
24 }
25 System . out . println ( Thread . currentThread () . getName () + " released lock on " + obj2 ) ;
26 }
27 System . out . println ( Thread . currentThread () . getName () + " released lock on " + obj1 ) ;
28 }
29 }
16 System . out . println ( Thread . currentThread () . getName () + " released lock on " + obj1 ) ;
17
18 System . out . println ( Thread . currentThread () . getName () + " acquiring lock on " + obj2 ) ;
19 synchronized ( obj2 ) {
20 System . out . println ( Thread . currentThread () . getName () + " acquired lock on " + obj2 ) ;
21 MyUtil . doSomething (5000) ;
22 }
23 System . out . println ( Thread . currentThread () . getName () + " released lock on " + obj2 ) ;
24 }
25 }
2.2.2 Livelock
- Create ’ThreadsLivelock’ project
- Create ’src/MyUtil.java’ file (https://gist.github.com/tsonkk/9219542d8ff75612110f95acc2fbe761)
1 public class MyUtil {
2 static void sleep ( long millis ) {
3 try {
4 Thread . sleep ( millis ) ;
5 } catch ( I n t erruptedException ex ) {
6 ex . printStackTrace () ;
7 }
8 }
9 }
19 do {
20 synchronized ( x ) {
21 x . increment () ;
22 r = x . getValue () ;
23 System . out . println ( Thread . currentThread () . getName () + " : x = " + r ) ;
24 }
25 MyUtil . sleep (1000) ;
26 } while ( r < 2) ;
27 }
28 private void run2 () {
29 int r = 0;
30 do {
31 synchronized ( x ) {
32 x . decrement () ;
33 r = x . getValue () ;
34 System . out . println ( Thread . currentThread () . getName () + " : x = " + r ) ;
35 }
36 MyUtil . sleep (1000) ;
37 } while ( r > -2) ;
38 }
39 }
2.2.3 Starvation
- Create ’ThreadsStarvation’ project
- Create ’src/MyUtil.java’ file (https://gist.github.com/tsonkk/db071a5da426210a705f8e43e4ee203a)
1 public class MyUtil {
2 static void doSomething ( long millis ) {
3 try {
4 Thread . sleep ( millis ) ;
5 } catch ( I n t erruptedException ex ) {
6 ex . printStackTrace () ;
7 }
8 }
9 }
2.3 Isolation
- Create ’ThreadsIsolation’ project
- Create ’src/Account.java’ file (https://gist.github.com/tsonkk/dafc2d237972261dbe4c8a91a808a42b)
1 public class Account {
2 String name ;
3 int balance ;
4
5 public Account ( int balance ) {
6 this . balance = balance ;
7 }
8 }
5 @Override
6 public void run () {
7 ...
8 /* sender . balance -= amount ;
9 receiver . balance += amount ; */
10 isolated (() -> {
11 sender . balance -= amount ;
12 receiver . balance += amount ;
13 }) ;
14 ...
15 }
16 }
31 } catch ( I n t erruptedException ex ) {
32 ex . printStackTrace () ;
33 }
34 }
35 }
3 Parallel Programming
3.1 Task Parallelism
- Create ’ForkJoinReciprocalArraySum’ project
- Create ’src/SumArray.java’ file (https://gist.github.com/tsonkk/a54877bdeb18df7a54d14efe7203370c)
1 import java . util . concurrent . RecursiveAction ;
2
3 public class SumArray extends RecursiveAction {
4 static int S E Q UENTIAL_THRESHOLD = 1000;
5 int lo , hi ;
6 double [] arr ;
7 double ans ;
8
9 public SumArray ( double [] a , int l , int h ) {
10 lo = l ;
11 hi = h ;
12 arr = a ;
13 }
14 @Override
15 protected void compute () {
16 if ( hi - lo <= SEQUENTIAL_THRESHOLD ) {
- Note that the results of the first/second run should be ignored because a JVM warm-up phase is needed, see
more details at:
• https://renaissance.dev/resources/docs/renaissance-suite.pdf
3.2.2 Streams
- Create ’StreamStudentAnalytics’ project
- Create ’src/Student.java’ file (https://gist.github.com/tsonkk/2d7c5b53294b4e516e65bec4c8d4fea8)
1 public class Student {
2 int id ;
3 boolean isCurrent ;
4 double age ;
5 }
37 System . out . printf ( " % s completed in %8.3 f milliseconds , with C [n -1][ n -1] = %8.5 f \ n " , name
, timeInNanos / 1 e6 , sum ) ;
38 }
39 public static void main ( String [] args ) {
40 final Random myRand = new Random () ;
41 // initialization
42 int n = 512;
43 double [][] A = new double [ n ][ n ];
44 double [][] B = new double [ n ][ n ];
45 double [][] C = new double [ n ][ n ];
46 /* for ( int i = 0; i < n ; i ++) {
47 for ( int j = 0; j < n ; j ++) {
48 A [ i ][ j ] = myRand . nextInt ( n ) ;
49 B [ i ][ j ] = myRand . nextInt ( n ) ;
50 C [ i ][ j ] = myRand . nextInt ( n ) ;
51 }
52 } */
53 forseq2d (0 , n -1 , 0 , n -1 , (i , j ) -> {
54 A [ i ][ j ] = myRand . nextInt ( n ) ;
55 B [ i ][ j ] = myRand . nextInt ( n ) ;
56 C [ i ][ j ] = myRand . nextInt ( n ) ;
57 }) ;
58 // run test
59 for ( int numRun = 1; numRun <= 5; numRun ++) {
60 System . out . printf ( " Run % d \ n " , numRun ) ;
61 seq Matrix Multiply (A , B , C , n ) ;
62 par Matrix Multiply (A , B , C , n ) ;
63 }
64 }
65 }
4 Distributed Programming
4.1 Client-Server
4.1.1 Unicast Communication (one-to-one)
4.1.1.1 OneServer - OneClient
7
8 public class EchoServer {
9 public void start ( int port ) throws IOException {
10 ServerSocket serverSocket = new ServerSocket ( port ) ;
11 System . out . println ( " Server started : " + serverSocket ) ;
12 oneClient ( serverSocket ) ;
13 serverSocket . close () ;
14 }
15 private void oneClient ( ServerSocket serverSocket ) throws IOException {
16 Socket clientSocket = serverSocket . accept () ;
17 PrintWriter out = new PrintWriter ( clientSocket . getOutputStream () , true ) ;
18 BufferedReader in = new BufferedReader ( new InputStreamReader ( clientSocket . getInputStream () )
);
19 String msg = " " ;
20 while (! " quit " . equals ( msg ) ) {
21 // receive from client
22 msg = in . readLine () . trim () ;
23 System . out . println ( clientSocket + " sent : " + msg ) ;
24 // send to client
25 out . println ( msg ) ;
26 }
27 in . close () ;
28 out . close () ;
29 clientSocket . close () ;
30 }
31 }
28 out . close () ;
29 clientSocket . close () ;
30 }
31 }
27 out . close () ;
28 clientSocket . close () ;
29 } catch ( IOException ex ) {
30 ex . printStackTrace () ;
31 }
32 }
33 }
- Run 2 clients with port = 7777 | 7778 first, and then run server
- Run 2 clients with IP = 192.168.1.2 | 192.168.1.3 first, and then run server
15 int [] y = { myrank };
16 int [] z = new int [1];
17 MPI . COMM_WORLD . Reduce (y , 0 , z , 0 , 1 , MPI . INT , MPI . SUM , 2) ; // reduce sum of ranks to R2
18 if ( myrank == 2) {
19 System . out . println ( " [ R " + myrank + " }: " + z [0]) ;
20 }
21 // gather
22 int [] yy = { myrank };
23 int [] zz = new int [ MPI . COMM_WORLD . Size () ];
24 MPI . COMM_WORLD . Gather ( yy , 0 , 1 , MPI . INT , zz , 0 , 1 , MPI . INT , 1) ; // gather ranks to R1
25 if ( myrank == 1) {
26 System . out . print ( " [ R " + myrank + " ]: " ) ;
27 for ( int ii : zz ) {
28 System . out . print ( ii + " " ) ;
29 }
30 }
31 MPI . Finalize () ;
32 }
33 }
27 // reduce
28 double [] sumReduce = new double [1];
29 MPI . COMM_WORLD . Reduce ( sumOnRank , 0 , sumReduce , 0 , 1 , MPI . DOUBLE , MPI . SUM , 0) ; // reduce
sumOnRank to R0
30 if ( myrank == 0) {
31 System . out . printf ( " [ R " + myrank + " ]: %8.5 f \ n " , sumReduce [0]) ; // for DEBUG
32 }
33 // gather
34 double [] sumGather = new double [ size ];
35 MPI . COMM_WORLD . Gather ( sumOnRank , 0 , 1 , MPI . DOUBLE , sumGather , 0 , 1 , MPI . DOUBLE , 1) ; //
gather sumOnRank to R1
36 double sumTotal = 0;
37 for ( double ii : sumGather ) {
38 sumTotal += ii ;
39 }
40 if ( myrank == 1) {
41 System . out . printf ( " [ R " + myrank + " ]: %8.5 f \ n " , sumTotal ) ; // for DEBUG
42 }
43 MPI . Finalize () ;
44 }
45 }
5 Exercises
5.1 Exercise Deadlock
- Preventing deadlocks for the Dining Philosophers problem.
2 int id ;
3 boolean isActive ;
4 int price ;
5 }
23 // send to client
24 // TODO
25 }
26 in . close () ;
27 out . close () ;
28 clientSocket . close () ;
29 } catch ( IOException ex ) {
30 ex . printStackTrace () ;
31 }
32 }
33 }
10 }
11 }
Acknowledgement
Many thanks to Prof. Vivek Sarkar ([email protected]), Rice University, for teaching the great specialization:
35