並行システム システム情報工学研究科コンピュータサイエンス専攻、電子・情報工学系 新城 靖 <yas@is.tsukuba.ac.jp>
このページは、次の URL にあります。
http://www.cs.tsukuba.ac.jp/~yas/sie/csys-2007/2007-12-21
あるいは、次のページから手繰っていくこともできます。
http://www.cs.tsukuba.ac.jp/~yas/sie/
http://www.cs.tsukuba.ac.jp/~yas/
http://gee.cs.oswego.edu/dl/cpj/
master() { 初期化; for( i=0 ; i<nthreads; i++ ) { pthread_create(,,slave,); } マスターの処理;/*必要なら*/ for( i=0 ; i<nthreads; i++ ) { pthread_join(,,slave,); } 終了処理;/*必要なら*/ } slave(void *params) { paramsからiを取り出す; 仕事をする; 結果を大域変数かparamsに返す; return; /* pthread_exit() */ }
図? 行列の掛け算
[MatrixMultiplyMaster.java]1: /* 2: * MatrixMultiplyMaster.java -- The master of MatrixMultiplySlave threads. 3: */ 4: 5: class MatrixMultiplyMaster { 6: public static double matrix_multiply_trace( double a[][], double b[][], 7: double c[][], int nthreads ) 8: throws java.lang.InterruptedException 9: { 10: int i; 11: MatrixMultiplySlave slaves[] = new MatrixMultiplySlave[nthreads]; 12: for( i=0; i<nthreads; i++ ) 13: { 14: slaves[i] = new MatrixMultiplySlave( a,b,c,i,nthreads ); 15: slaves[i].start(); 16: } 17: double trace = 0.0; 18: for( i=0; i<nthreads; i++ ) 19: { 20: slaves[i].join(); 21: trace += slaves[i].get_trace(); 22: } 23: return( trace ); 24: } 25: }[MatrixMultiplySlave.java]
1: /* 2: * MatrixMultiplySlave.java -- Slave threads for Matrix multiplication. 3: */ 4: 5: class MatrixMultiplySlave extends java.lang.Thread { 6: double[][] a, b, c; 7: int i,n ; 8: double trace_ans = 0.0 ; 9: public MatrixMultiplySlave( double a[][], double b[][], double c[][], 10: int i, int n ) 11: { 12: this.a = a ; this.b = b ; this.c = c ; 13: this.i = i ; this.n = n ; 14: double trace = 0.0; 15: } 16: public void run() 17: { 18: int c_nrows = Matrix.nrows(c), c_ncols = Matrix.ncols(c), 19: a_ncols = Matrix.ncols(a); 20: int quot = c_nrows /n; int rem = c_nrows % n; 21: int do_rows = quot + (i < rem ? 1 : 0); 22: int first_row = quot * i + (i < rem ? i : rem); 23: double trace = 0.0; 24: 25: int row, col, j; 26: for( row = first_row; row < first_row + do_rows; row++ ) 27: { 28: for( col=0; col < c_ncols; col++ ) 29: { 30: double sum = 0.0; 31: for( j = 0; j < a_ncols; j++ ) 32: { 33: sum += a[row][j] * b[j][col]; 34: } 35: c[row][col] = sum; 36: if( row == col ) 37: { 38: trace += sum; 39: } 40: } 41: } 42: trace_ans = trace; 43: } 44: public double get_trace() 45: { 46: return( trace_ans ); 47: } 48: }[MatrixMultiplyDemo.java]
1: /* 2: * MatrixMultiplyDemo.java -- run and measure execution time of MatrixMultiply. 3: */ 4: 5: class MatrixMultiplyDemo { 6: public static void main(String argv[]) 7: throws java.lang.InterruptedException 8: { 9: if( argv.length != 3 ) 10: { 11: System.err.println("Usage:% java MatrixMultiplyDemo matrix-size nthreads niters"); 12: System.err.println("Hints: matrix-size: 200..400, nthreads: 1..nCPU, niters: 1..100"); 13: System.exit( 1 ); 14: } 15: int matrix_size = Integer.parseInt( argv[0] ); 16: int nthreads = Integer.parseInt( argv[1] ); 17: int niters = Integer.parseInt( argv[2] ); 18: run_matrix_multiply_trace( matrix_size, nthreads, niters ); 19: System.exit( 0 ); 20: } 21: static void run_matrix_multiply_trace( int matrix_size, int nthreads, 22: int niters ) 23: throws java.lang.InterruptedException 24: { 25: // pthread_setconcurrency( nthreads ); 26: double a[][] = Matrix.alloc( matrix_size, matrix_size ); 27: double b[][] = Matrix.alloc( matrix_size, matrix_size ); 28: double c[][] = Matrix.alloc( matrix_size, matrix_size ); 29: java.util.Random r = new java.util.Random(); 30: Matrix.fill_rand( a,r ); 31: Matrix.fill_rand( b,r ); 32: Matrix.fill_rand( c,r ); 33: long start = System.currentTimeMillis(); 34: for( int i=0; i<niters; i++ ) 35: { 36: MatrixMultiplyMaster.matrix_multiply_trace( a,b,c,nthreads ); 37: } 38: long end = System.currentTimeMillis(); 39: double diff = (double)(end - start)/1000.0 ; 40: int concurrency = 0; // pthread_getconcurrency(); 41: System.out.printf("matrix_size==%d, nthreads==%d, niters==%d, concurrency==%d\n", 42: matrix_size, nthreads, niters, concurrency ); 43: System.out.printf("%6.3f [sec] / %d [iteration] == %6.3f [sec/iteration]\n", 44: diff, niters, diff/niters ); 45: System.out.printf("%d [iteration] / %6.3f [sec] == %6.3f [iteration/sec]\n", 46: niters, diff, niters/diff ); 47: } 48: }[Matrix.java]
/* * Matrix.java -- Simple matrix with wo-dimensional array. */ class Matrix { public static double[][] alloc( int rows, int cols ) { double m[][]; m = new double[rows][cols]; return( m ); } public static void fill_rand( double m[][], java.util.Random r ) { int m_nrows = nrows( m ); int m_ncols = ncols( m ); for( int i=0; i<m_nrows; i++ ) for( int j=0; j<m_ncols; j++ ) m[i][j] = r.nextDouble(); } public static int nrows( double m[][] ) { return( m.length ); } public static int ncols( double m[][] ) { return( m[0].length ); } }
% wget http://www.cs.tsukuba.ac.jp/~yas/sie/csys-2007/2007-12-21/ex/MatrixMultiplyMaster.java% wget http://www.cs.tsukuba.ac.jp/~yas/sie/csys-2007/2007-12-21/ex/MatrixMultiplySlave.java
% wget http://www.cs.tsukuba.ac.jp/~yas/sie/csys-2007/2007-12-21/ex/MatrixMultiplyDemo.java
% wget http://www.cs.tsukuba.ac.jp/~yas/sie/csys-2007/2007-12-21/ex/Matrix.java
% javac MatrixMultiplyMaster.java MatrixMultiplySlave.java MatrixMultiplyDemo.java Matrix.java
% java -version
java version "1.5.0_14" Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_14-b03) Java HotSpot(TM) Server VM (build 1.5.0_14-b03, mixed mode) % java MatrixMultiplyDemo
Usage:% java MatrixMultiplyDemo matrix-size nthreads niters Hints: matrix-size: 200..400, nthreads: 1..nCPU, niters: 1..100 % java MatrixMultiplyDemo
Usage:% java MatrixMultiplyDemo matrix-size nthreads niters Hints: matrix-size: 200..400, nthreads: 1..nCPU, niters: 1..100 % java MatrixMultiplyDemo 300 1 1
matrix_size==300, nthreads==1, niters==1, concurrency==0 3.586 [sec] / 1 [iteration] == 3.586 [sec/iteration] 1 [iteration] / 3.586 [sec] == 0.279 [iteration/sec] % java MatrixMultiplyDemo 300 2 1
matrix_size==300, nthreads==2, niters==1, concurrency==0 1.819 [sec] / 1 [iteration] == 1.819 [sec/iteration] 1 [iteration] / 1.819 [sec] == 0.550 [iteration/sec] % java MatrixMultiplyDemo 300 3 1
matrix_size==300, nthreads==3, niters==1, concurrency==0 1.229 [sec] / 1 [iteration] == 1.229 [sec/iteration] 1 [iteration] / 1.229 [sec] == 0.814 [iteration/sec] % java MatrixMultiplyDemo 300 4 1
matrix_size==300, nthreads==4, niters==1, concurrency==0 0.936 [sec] / 1 [iteration] == 0.936 [sec/iteration] 1 [iteration] / 0.936 [sec] == 1.068 [iteration/sec] % java MatrixMultiplyDemo 300 5 1
matrix_size==300, nthreads==5, niters==1, concurrency==0 1.061 [sec] / 1 [iteration] == 1.061 [sec/iteration] 1 [iteration] / 1.061 [sec] == 0.943 [iteration/sec] %
![]()
% wget http://www.cs.tsukuba.ac.jp/~yas/sie/csys-2007/2007-12-21/ex/ms_matrix-main.c% wget http://www.cs.tsukuba.ac.jp/~yas/sie/csys-2007/2007-12-21/ex/ms_matrix.c
% wget http://www.cs.tsukuba.ac.jp/~yas/sie/csys-2007/2007-12-21/ex/timeval.c
% wget http://www.cs.tsukuba.ac.jp/~yas/sie/csys-2007/2007-12-21/ex/Makefile
% emacs Makefile (CFLAGSの調整)
% make ms_matrix-main
gcc -D_REENTRANT ms_matrix-main.o -lpthread -lposix4 -o ms_matrix-main % ./ms_matrix-main 400 1 1
matrix_size==400, nthreads==1, niters==1, concurrency==1 1.846 [sec] / 1 [iteration] == 1.846 [sec/iteration] 1 [iteration] / 1.846 [sec] == 0.542 [iteration/sec] % ./ms_matrix-main 400 1 1
matrix_size==400, nthreads==1, niters==1, concurrency==1 1.842 [sec] / 1 [iteration] == 1.842 [sec/iteration] 1 [iteration] / 1.842 [sec] == 0.543 [iteration/sec] % ./ms_matrix-main 400 2 1
matrix_size==400, nthreads==2, niters==1, concurrency==2 0.924 [sec] / 1 [iteration] == 0.924 [sec/iteration] 1 [iteration] / 0.924 [sec] == 1.082 [iteration/sec] % ./ms_matrix-main 400 3 1
matrix_size==400, nthreads==3, niters==1, concurrency==3 0.657 [sec] / 1 [iteration] == 0.657 [sec/iteration] 1 [iteration] / 0.657 [sec] == 1.523 [iteration/sec] % ./ms_matrix-main 400 4 1
matrix_size==400, nthreads==4, niters==1, concurrency==4 0.467 [sec] / 1 [iteration] == 0.467 [sec/iteration] 1 [iteration] / 0.467 [sec] == 2.144 [iteration/sec] % ./ms_matrix-main 400 5 1
matrix_size==400, nthreads==5, niters==1, concurrency==5 0.728 [sec] / 1 [iteration] == 0.728 [sec/iteration] 1 [iteration] / 0.728 [sec] == 1.374 [iteration/sec] %
![]()
http://www.atmarkit.co.jp/fjava/rensai3/devedge03/devedge03_1.html
http://www.shudo.net/article/hotspot_threads/threads.html
master() { 初期化; for( i=0 ; i<nthreads; i++ ) { pthread_create(,,slave,); } while( !termcond ) { マスターの処理A;/*必要なら*/ barrier_wait(); マスターの処理B;/*必要なら*/ barrier_wait(); } for( i=0 ; i<nthreads; i++ ) { pthread_join(,,slave,); } 終了処理;/*必要なら*/ } slave(void *params) { paramsからiを取り出す; while( !termcond ) { /* マスターの処理Aの完了を待つ */ barrier_wait(); スレーブ処理B; 結果を大域変数かparamsに返す; barrier_wait(); } return; /* pthread_exit() */ }ループの間、マスタの仕事がないこともある。その場合は、マスタはバリアに は参加しない(relax.c参照)。
図? 弛緩法
1: /* 2: * RelaxMaster.java -- The Master thread for the relax method. 3: */ 4: 5: import java.util.concurrent.CyclicBarrier; 6: 7: class RelaxMaster { 8: RelaxSlave slaves[]; 9: int nthreads; 10: public RelaxMaster( double boundary[][], double t[][], 11: final int nthreads) 12: { 13: this.nthreads = nthreads; 14: CyclicBarrier barrier = 15: new CyclicBarrier( nthreads, 16: new Runnable() { 17: public synchronized void run() { 18: all_done = n_done == nthreads; 19: n_done = 0; 20: } 21: } 22: ); 23: double t_temp[][] = Matrix.alloc( Matrix.nrows(t), Matrix.ncols(t) ); 24: slaves = new RelaxSlave[nthreads]; 25: int i; 26: for( i=0; i<nthreads; i++ ) 27: { 28: slaves[i] = new RelaxSlave( i,nthreads, boundary, t, t_temp, 29: barrier, this ); 30: } 31: } 32: public void relax() 33: throws java.lang.InterruptedException 34: { 35: int i; 36: for( i=0; i<nthreads; i++ ) 37: { 38: slaves[i].start(); 39: } 40: for( i=0; i<nthreads; i++ ) 41: { 42: slaves[i].join(); 43: } 44: } 45: int n_done = 0; 46: boolean all_done = false; 47: public synchronized void i_am_done() 48: { 49: n_done ++; 50: } 51: public synchronized boolean all_done() 52: { 53: return( all_done ); 54: } 55: }[RelaxSlave.java]
1: /* 2: * RelaxSlave.java -- Slave threads for relax method 3: */ 4: 5: import java.util.concurrent.CyclicBarrier; 6: 7: class RelaxSlave extends java.lang.Thread { 8: double[][] boundary, t, t_temp; 9: int i,n ; 10: CyclicBarrier barrier; 11: RelaxMaster master; 12: public RelaxSlave( int i, int n, double boundary[][], double t[][], 13: double t_temp[][], CyclicBarrier barrier, 14: RelaxMaster master) 15: { 16: this.i = i ; this.n = n ; 17: this.boundary = boundary ; this.t = t ; this.t_temp = t_temp ; 18: this.barrier = barrier; 19: this.master = master; 20: } 21: public void run() 22: { 23: double t_old[][] = this.t; 24: double t_new[][] = this.t_temp; 25: int quot = Matrix.nrows(boundary) / n; 26: int rem = Matrix.nrows(boundary) % n; 27: int do_rows = quot + (i < rem ? 1 : 0); 28: int first_row = quot * i + (i < rem ? i : rem); 29: double temp[][]; 30: 31: int row, col; 32: boolean converged; 33: // int n_done; 34: 35: do { 36: converged = true; 37: for( row = first_row; row < first_row + do_rows; row++ ) 38: { 39: for( col = 0; col < Matrix.ncols(boundary); col++ ) 40: { 41: if( boundary[row][col] == 0 ) 42: { 43: double v = 44: (t_old[row-1][col] + 45: t_old[row+1][col] + 46: t_old[row ][col-1] + 47: t_old[row ][col+1]) / 4.0; 48: if( java.lang.Math.abs(v-t_old[row][col]) > 0.000001) 49: converged = false; 50: t_new[row][col] = v; 51: } 52: else 53: { 54: t_new[row][col] = t_old[row][col]; 55: } 56: } 57: } 58: try 59: { 60: if( converged && t_new == this.t ) 61: master.i_am_done(); 62: barrier.await(); 63: } 64: catch( java.lang.InterruptedException e) 65: { 66: return; 67: } 68: catch( java.util.concurrent.BrokenBarrierException e) 69: { 70: return; 71: } 72: temp = t_new; t_new = t_old; t_old = temp; 73: } while( !master.all_done() ); 74: } 75: }[RelaxDemo.java]
1: /* 2: * RelaxDemo.java -- run and measure execution time of Relax. 3: */ 4: 5: class RelaxDemo { 6: public static void main(String argv[]) 7: throws java.lang.InterruptedException 8: { 9: if( argv.length != 3 ) 10: { 11: System.err.println("Usage:% java RelaxDemo matrix-size nthreads niters"); 12: System.err.println("Hints: matrix-size: 40..60, nthreads: 1..nCPU, niters: 1..100"); 13: System.exit( 1 ); 14: } 15: int matrix_size = Integer.parseInt( argv[0] ); 16: int nthreads = Integer.parseInt( argv[1] ); 17: int niters = Integer.parseInt( argv[2] ); 18: run_relax( matrix_size, nthreads, niters ); 19: System.exit( 0 ); 20: } 21: static void run_relax( int matrix_size, int nthreads, 22: int niters ) 23: throws java.lang.InterruptedException 24: { 25: // pthread_setconcurrency( nthreads ); 26: double t[][] = Matrix.alloc( matrix_size, matrix_size ); 27: double boundary[][] = Matrix.alloc( matrix_size, matrix_size ); 28: matrix_t_fill( t ); 29: matrix_boundary_fill( boundary ); 30: long start = System.currentTimeMillis(); 31: for( int i=0; i<niters; i++ ) 32: { 33: RelaxMaster m = new RelaxMaster( boundary, t, nthreads ); 34: m.relax(); 35: } 36: long end = System.currentTimeMillis(); 37: double diff = (double)(end - start)/1000.0 ; 38: int concurrency = 0; // pthread_getconcurrency(); 39: System.out.printf("matrix_size==%d, nthreads==%d, niters==%d, concurrency==%d\n", 40: matrix_size, nthreads, niters, concurrency ); 41: System.out.printf("%6.3f [sec] / %d [iteration] == %6.3f [sec/iteration]\n", 42: diff, niters, diff/niters ); 43: System.out.printf("%d [iteration] / %6.3f [sec] == %6.3f [iteration/sec]\n", 44: niters, diff, niters/diff ); 45: } 46: static void matrix_t_fill( double t[][] ) 47: { 48: int n_rows = Matrix.nrows( t ); 49: int n_cols = Matrix.nrows( t ); 50: int i,j; 51: for( i=0 ; i<n_rows; i++ ) 52: { 53: for( j=0; j<n_cols; j++ ) 54: { 55: t[i][j] = 0.0 ; 56: } 57: } 58: j = n_cols/2 ; 59: for( i=0 ; i<n_rows; i++ ) 60: { 61: t[i][j] = 1.0 ; 62: } 63: i = n_cols/2 ; 64: for( j=0; j<n_cols; j++ ) 65: { 66: t[i][j] = 1.0 ; 67: } 68: } 69: static void matrix_boundary_fill( double m[][] ) 70: { 71: int n_rows = Matrix.nrows( m ); 72: int n_cols = Matrix.nrows( m ); 73: int i,j ; 74: for( i=0 ; i<n_rows; i++ ) 75: { 76: for( j=0; j<n_cols; j++ ) 77: { 78: m[i][j] = 0 ; 79: } 80: } 81: for( i=0 ; i<n_rows; i++ ) 82: { 83: m[i][0] = 1 ; 84: m[i][n_cols-1] = 1 ; 85: } 86: for( j=0; j<n_cols; j++ ) 87: { 88: m[0][j] = 1 ; 89: m[n_rows-1][j] = 1 ; 90: } 91: } 92: }
% wget http://www.cs.tsukuba.ac.jp/~yas/sie/csys-2007/2007-12-21/ex/RelaxMaster.java% wget http://www.cs.tsukuba.ac.jp/~yas/sie/csys-2007/2007-12-21/ex/RelaxSlave.java
% wget http://www.cs.tsukuba.ac.jp/~yas/sie/csys-2007/2007-12-21/ex/RelaxDemo.java
% wget http://www.cs.tsukuba.ac.jp/~yas/sie/csys-2007/2007-12-21/ex/Matrix.java
% javac RelaxMaster.java RelaxSlave.java RelaxDemo.java Matrix.java
% java RelaxDemo
Usage:% java RelaxDemo matrix-size nthreads niters Hints: matrix-size: 40..60, nthreads: 1..nCPU, niters: 1..100 % java RelaxDemo 60 1 1
matrix_size==60, nthreads==1, niters==1, concurrency==0 4.026 [sec] / 1 [iteration] == 4.026 [sec/iteration] 1 [iteration] / 4.026 [sec] == 0.248 [iteration/sec] % java RelaxDemo 60 2 1
matrix_size==60, nthreads==2, niters==1, concurrency==0 2.751 [sec] / 1 [iteration] == 2.751 [sec/iteration] 1 [iteration] / 2.751 [sec] == 0.364 [iteration/sec] % java RelaxDemo 60 3 1
matrix_size==60, nthreads==3, niters==1, concurrency==0 2.415 [sec] / 1 [iteration] == 2.415 [sec/iteration] 1 [iteration] / 2.415 [sec] == 0.414 [iteration/sec] % java RelaxDemo 60 4 1
matrix_size==60, nthreads==4, niters==1, concurrency==0 2.357 [sec] / 1 [iteration] == 2.357 [sec/iteration] 1 [iteration] / 2.357 [sec] == 0.424 [iteration/sec] %
![]()
% wget http://www.cs.tsukuba.ac.jp/~yas/sie/csys-2007/2007-12-21/ex/ms_relax.c% wget http://www.cs.tsukuba.ac.jp/~yas/sie/csys-2007/2007-12-21/ex/ms_relax-main.c
% wget http://www.cs.tsukuba.ac.jp/~yas/sie/csys-2007/2007-12-21/ex/barrier.c
% wget http://www.cs.tsukuba.ac.jp/~yas/sie/csys-2007/2007-12-21/ex/timeval.c
% wget http://www.cs.tsukuba.ac.jp/~yas/sie/csys-2007/2007-12-21/ex/Makefile
% emacs Makefile (CFLAGSの調整)
% make ms_relax-main.c
% ./ms_relax-main 50 1 1
matrix_size==50, nthreads==1, niters==1, concurrency==1 1.575 [sec] / 1 [iteration] == 1.575 [sec/iteration] 1 [iteration] / 1.575 [sec] == 0.635 [iteration/sec] % ./ms_relax-main 50 1 1
matrix_size==50, nthreads==1, niters==1, concurrency==1 1.572 [sec] / 1 [iteration] == 1.572 [sec/iteration] 1 [iteration] / 1.572 [sec] == 0.636 [iteration/sec] % ./ms_relax-main 50 2 1
matrix_size==50, nthreads==2, niters==1, concurrency==2 0.857 [sec] / 1 [iteration] == 0.857 [sec/iteration] 1 [iteration] / 0.857 [sec] == 1.167 [iteration/sec] % ./ms_relax-main 50 3 1
matrix_size==50, nthreads==3, niters==1, concurrency==3 0.646 [sec] / 1 [iteration] == 0.646 [sec/iteration] 1 [iteration] / 0.646 [sec] == 1.547 [iteration/sec] % ./ms_relax-main 50 4 1
matrix_size==50, nthreads==4, niters==1, concurrency==4 0.938 [sec] / 1 [iteration] == 0.938 [sec/iteration] 1 [iteration] / 0.938 [sec] == 1.066 [iteration/sec] % uptime
1:06am up 116 day(s), 14:35, 7 users, load average: 1.33, 1.14, 1.10 %
![]()
worker_thraed() { while( (ptr=work_get(workpile))!=NULL ) { ptrが示す仕事をする; if( 新しい仕事ができた ) { work_put(workpile,新しい仕事); } } }
図? タスクバッグ
1: /* 2: * QuickSort.java -- Multithreaded quick sort with a task bag 3: */ 4: 5: import java.util.concurrent.Executor; 6: import java.util.concurrent.ExecutorService; 7: import java.util.concurrent.Executors; 8: 9: class QuickSortTask implements Runnable { 10: double data[]; 11: int base; 12: int n; 13: QuickSort manager; 14: public QuickSortTask( double data[], int base, int n, 15: QuickSort manager ) 16: { 17: this.data = data ; 18: this.base = base ; 19: this.n = n ; 20: this.manager = manager ; 21: } 22: static final int SORT_DIRECT = 200; 23: public void run() 24: { 25: int i,j; 26: if( n <= SORT_DIRECT ) 27: { 28: for( j=1; j<n; j++) 29: { 30: double key = data[base+j]; 31: for( i=j-1; i >= 0 && key < data[base+i]; i--) 32: data[base+i+1] = data[base+i]; 33: data[base+i+1] = key; 34: } 35: manager.task_done(); 36: return; 37: } 38: i = 0; 39: j = n - 1; 40: while( true ) 41: { 42: while( data[base+i] < data[base+j] ) j--; 43: if( i >= j ) break; 44: { double t = data[base+i]; data[base+i] = data[base+j]; 45: data[base+j] = t; } /* swap */ 46: i++; 47: while( data[base+i] < data[base+j] ) i++; 48: if (i >= j) { i = j; break; } 49: { double t = data[base+i]; data[base+i] = data[base+j]; 50: data[base+j] = t; } /* swap */ 51: j--; 52: } 53: manager.add_task( data,base, i ); 54: manager.add_task( data,base+i+1,n-i-1 ); 55: manager.task_done(); 56: } 57: } 58: 59: class QuickSort { 60: int task_count; 61: ExecutorService exec; 62: public QuickSort(int n_threads) 63: { 64: task_count = 0; 65: exec = Executors.newFixedThreadPool(n_threads); 66: } 67: public synchronized void add_task( double data[], int base, int n ) 68: { 69: task_count ++; 70: Runnable task = new QuickSortTask( data,base,n,this ); 71: exec.execute( task ); 72: } 73: public synchronized void task_done() 74: { 75: task_count -- ; 76: if( task_count <= 0 ) 77: notify(); 78: } 79: public synchronized void work_wait() 80: throws java.lang.InterruptedException 81: { 82: while( task_count > 0 ) 83: { 84: wait(); 85: } 86: exec.shutdown(); 87: } 88: }[QuickSortDemo.java]
1: /* 2: * QuicksortDemo.java -- run and measure execution time of Quicksort. 3: */ 4: 5: class QuickSortDemo { 6: public static void main(String argv[]) 7: throws java.lang.InterruptedException 8: { 9: if( argv.length != 2 ) 10: { 11: System.err.println("Usage:% java QuicksortDemo matrix-size nthreads"); 12: System.err.println("Hints: matrix-size: 1000000, nthreads: 1..nCPU"); 13: System.exit( 1 ); 14: } 15: int matrix_size = Integer.parseInt( argv[0] ); 16: int nthreads = Integer.parseInt( argv[1] ); 17: run_quicksort( matrix_size, nthreads ); 18: System.exit( 0 ); 19: } 20: static void run_quicksort( int matrix_size, int nthreads ) 21: throws java.lang.InterruptedException 22: { 23: // pthread_setconcurrency( nthreads ); 24: double data[] = new double[matrix_size]; 25: data_fill( data,matrix_size ); 26: long start = System.currentTimeMillis(); 27: QuickSort qs = new QuickSort( nthreads ); 28: qs.add_task( data,0,matrix_size ); 29: qs.work_wait(); 30: long end = System.currentTimeMillis(); 31: double diff = (double)(end - start)/1000.0 ; 32: int concurrency = 0; // pthread_getconcurrency(); 33: int niters = 1; 34: System.out.printf("matrix_size==%d, nthreads==%d, niters==%d, concurrency==%d\n", 35: matrix_size, nthreads, niters, concurrency ); 36: System.out.printf("%6.3f [sec] / %d [iteration] == %6.3f [sec/iteration]\n", 37: diff, niters, diff/niters ); 38: System.out.printf("%d [iteration] / %6.3f [sec] == %6.3f [iteration/sec]\n", 39: niters, diff, niters/diff ); 40: } 41: static void data_fill( double data[], int size ) 42: { 43: int i; 44: java.util.Random r = new java.util.Random(); 45: for( i=0 ; i<size; i++ ) 46: { 47: data[i] = r.nextDouble(); 48: } 49: } 50: static void data_print( double data[], int size ) 51: { 52: int i; 53: for( i=0 ; i<size; i++ ) 54: { 55: System.out.printf("%4.2f ",data[i]); 56: } 57: System.out.printf("\n"); 58: } 59: }
% wget http://www.cs.tsukuba.ac.jp/~yas/sie/csys-2007/2007-12-21/ex/QuickSort.java% wget http://www.cs.tsukuba.ac.jp/~yas/sie/csys-2007/2007-12-21/ex/QuickSortDemo.java
% javac QuickSort.java QuickSortDemo.java
% java QuickSortDemo
Usage:% java QuicksortDemo matrix-size nthreads Hints: matrix-size: 1000000, nthreads: 1..nCPU % java QuickSortDemo 1000000 1
matrix_size==1000000, nthreads==1, niters==1, concurrency==0 3.830 [sec] / 1 [iteration] == 3.830 [sec/iteration] 1 [iteration] / 3.830 [sec] == 0.261 [iteration/sec] % java QuickSortDemo 1000000 2
matrix_size==1000000, nthreads==2, niters==1, concurrency==0 2.210 [sec] / 1 [iteration] == 2.210 [sec/iteration] 1 [iteration] / 2.210 [sec] == 0.452 [iteration/sec] % java QuickSortDemo 1000000 3
matrix_size==1000000, nthreads==3, niters==1, concurrency==0 1.768 [sec] / 1 [iteration] == 1.768 [sec/iteration] 1 [iteration] / 1.768 [sec] == 0.566 [iteration/sec] % java QuickSortDemo 1000000 4
matrix_size==1000000, nthreads==4, niters==1, concurrency==0 1.736 [sec] / 1 [iteration] == 1.736 [sec/iteration] 1 [iteration] / 1.736 [sec] == 0.576 [iteration/sec] %
![]()
% wget http://www.cs.tsukuba.ac.jp/~yas/sie/csys-2007/2007-12-21/ex/quicksort-main.c% wget http://www.cs.tsukuba.ac.jp/~yas/sie/csys-2007/2007-12-21/ex/quicksort.c
% wget http://www.cs.tsukuba.ac.jp/~yas/sie/csys-2007/2007-12-21/ex/workpile.c
% wget http://www.cs.tsukuba.ac.jp/~yas/sie/csys-2007/2007-12-21/ex/timeval.c
% wget http://www.cs.tsukuba.ac.jp/~yas/sie/csys-2007/2007-12-21/ex/Makefile
% emacs Makefile (CFLAGSの調整)
% make quicksort-main
% ./quicksort-main 1000000 1
size==1000000, nthreads==1, concurrency==1 execution time: 0.766 [sec] throughput: 1.305 [/sec] % ./quicksort-main 1000000 1
size==1000000, nthreads==1, concurrency==1 execution time: 0.761 [sec] throughput: 1.315 [/sec] % ./quicksort-main 1000000 2
size==1000000, nthreads==2, concurrency==2 execution time: 0.439 [sec] throughput: 2.280 [/sec] % ./quicksort-main 1000000 3
size==1000000, nthreads==3, concurrency==3 execution time: 0.334 [sec] throughput: 2.993 [/sec] % ./quicksort-main 1000000 4
size==1000000, nthreads==4, concurrency==4 execution time: 0.318 [sec] throughput: 3.145 [/sec] % ./quicksort-main 1000000 5
size==1000000, nthreads==5, concurrency==5 execution time: 0.276 [sec] throughput: 3.621 [/sec] %
![]()
コンパイル時: -pg オプションを付ける。
実行すると gmon.out というファイルが作られる。 これを、実行形式ファイルと共に gprof コマンドに渡す。
プログラミング言語としては、C言語、または、Java を用いなさい。
プログラミング言語としては、C言語、または、Java を用いなさい。
プログラミング言語としては、C言語、または、Java を用いなさい。
プログラミング言語としては、C言語、または、Java を用いなさい。