11package ru .javaops .masterjava .matrix ;
22
3- import java .util .*;
3+ import java .util .ArrayList ;
4+ import java .util .List ;
5+ import java .util .Random ;
46import java .util .concurrent .*;
5- import java .util .stream .Collectors ;
67import java .util .stream .IntStream ;
78
8- /**
9- * gkislin
10- * 03.07.2016
11- */
129public class MatrixUtil {
1310
14- public static int [][] concurrentMultiply (int [][] matrixA , int [][] matrixB , ExecutorService executor ) throws InterruptedException , ExecutionException {
15- final int matrixSize = matrixA .length ;
16- final int [][] matrixC = new int [matrixSize ][matrixSize ];
17-
18- class ColumnMultipleResult {
19- private final int col ;
20- private final int [] columnC ;
21-
22- private ColumnMultipleResult (int col , int [] columnC ) {
23- this .col = col ;
24- this .columnC = columnC ;
25- }
26- }
27-
28- final CompletionService <ColumnMultipleResult > completionService = new ExecutorCompletionService <>(executor );
29-
30- for (int j = 0 ; j < matrixSize ; j ++) {
31- final int col = j ;
32- final int [] columnB = new int [matrixSize ];
33- for (int k = 0 ; k < matrixSize ; k ++) {
34- columnB [k ] = matrixB [k ][col ];
35- }
36- completionService .submit (() -> {
37- final int [] columnC = new int [matrixSize ];
38-
39- for (int row = 0 ; row < matrixSize ; row ++) {
40- final int [] rowA = matrixA [row ];
41- int sum = 0 ;
42- for (int k = 0 ; k < matrixSize ; k ++) {
43- sum += rowA [k ] * columnB [k ];
44- }
45- columnC [row ] = sum ;
46- }
47- return new ColumnMultipleResult (col , columnC );
48- });
49- }
50-
51- for (int i = 0 ; i < matrixSize ; i ++) {
52- ColumnMultipleResult res = completionService .take ().get ();
53- for (int k = 0 ; k < matrixSize ; k ++) {
54- matrixC [k ][res .col ] = res .columnC [k ];
55- }
56- }
57- return matrixC ;
58- }
59-
60- public static int [][] concurrentMultiplyCayman (int [][] matrixA , int [][] matrixB , ExecutorService executor ) throws InterruptedException , ExecutionException {
61- final int matrixSize = matrixA .length ;
62- final int [][] matrixResult = new int [matrixSize ][matrixSize ];
63- final int threadCount = Runtime .getRuntime ().availableProcessors ();
64- final int maxIndex = matrixSize * matrixSize ;
65- final int cellsInThread = maxIndex / threadCount ;
66- final int [][] matrixBFinal = new int [matrixSize ][matrixSize ];
67-
68- for (int i = 0 ; i < matrixSize ; i ++) {
69- for (int j = 0 ; j < matrixSize ; j ++) {
70- matrixBFinal [i ][j ] = matrixB [j ][i ];
71- }
72- }
73-
74- Set <Callable <Boolean >> threads = new HashSet <>();
75- int fromIndex = 0 ;
76- for (int i = 1 ; i <= threadCount ; i ++) {
77- final int toIndex = i == threadCount ? maxIndex : fromIndex + cellsInThread ;
78- final int firstIndexFinal = fromIndex ;
79- threads .add (() -> {
80- for (int j = firstIndexFinal ; j < toIndex ; j ++) {
81- final int row = j / matrixSize ;
82- final int col = j % matrixSize ;
83-
84- int sum = 0 ;
85- for (int k = 0 ; k < matrixSize ; k ++) {
86- sum += matrixA [row ][k ] * matrixBFinal [col ][k ];
87- }
88- matrixResult [row ][col ] = sum ;
89- }
90- return true ;
91- });
92- fromIndex = toIndex ;
93- }
94- executor .invokeAll (threads );
95- return matrixResult ;
96- }
97-
98- public static int [][] concurrentMultiplyDarthVader (int [][] matrixA , int [][] matrixB , ExecutorService executor )
11+ public static int [][] concurrentMultiplyStreams (int [][] matrixA , int [][] matrixB , int threadNumber )
9912 throws InterruptedException , ExecutionException {
10013
10114 final int matrixSize = matrixA .length ;
10215 final int [][] matrixC = new int [matrixSize ][matrixSize ];
10316
104- List <Callable <Void >> tasks = IntStream .range (0 , matrixSize )
105- .parallel ()
106- .mapToObj (i -> new Callable <Void >() {
107- private final int [] tempColumn = new int [matrixSize ];
108-
109- @ Override
110- public Void call () throws Exception {
111- for (int c = 0 ; c < matrixSize ; c ++) {
112- tempColumn [c ] = matrixB [c ][i ];
113- }
114- for (int j = 0 ; j < matrixSize ; j ++) {
115- int row [] = matrixA [j ];
116- int sum = 0 ;
117- for (int k = 0 ; k < matrixSize ; k ++) {
118- sum += tempColumn [k ] * row [k ];
17+ new ForkJoinPool (threadNumber ).submit (
18+ () -> IntStream .range (0 , matrixSize )
19+ .parallel ()
20+ .forEach (row -> {
21+ final int [] rowA = matrixA [row ];
22+ final int [] rowC = matrixC [row ];
23+
24+ for (int idx = 0 ; idx < matrixSize ; idx ++) {
25+ final int elA = rowA [idx ];
26+ final int [] rowB = matrixB [idx ];
27+ for (int col = 0 ; col < matrixSize ; col ++) {
28+ rowC [col ] += elA * rowB [col ];
29+ }
11930 }
120- matrixC [j ][i ] = sum ;
121- }
122- return null ;
123- }
124- })
125- .collect (Collectors .toList ());
31+ })).get ();
12632
127- executor .invokeAll (tasks );
12833 return matrixC ;
12934 }
13035
131- public static int [][] concurrentMultiply2 (int [][] matrixA , int [][] matrixB , ExecutorService executor ) throws InterruptedException , ExecutionException {
36+ public static int [][] concurrentMultiply (int [][] matrixA , int [][] matrixB , ExecutorService executor ) throws InterruptedException , ExecutionException {
13237 final int matrixSize = matrixA .length ;
13338 final int [][] matrixC = new int [matrixSize ][];
13439
@@ -161,7 +66,30 @@ public static int[][] concurrentMultiply2(int[][] matrixA, int[][] matrixB, Exec
16166 return matrixC ;
16267 }
16368
164- // Optimized by https://habrahabr.ru/post/114797/
69+ public static int [][] concurrentMultiply2 (int [][] matrixA , int [][] matrixB , ExecutorService executor ) throws InterruptedException {
70+ final int matrixSize = matrixA .length ;
71+ final int [][] matrixC = new int [matrixSize ][matrixSize ];
72+ final CountDownLatch latch = new CountDownLatch (matrixSize );
73+
74+ for (int row = 0 ; row < matrixSize ; row ++) {
75+ final int [] rowA = matrixA [row ];
76+ final int [] rowC = matrixC [row ];
77+
78+ executor .submit (() -> {
79+ for (int idx = 0 ; idx < matrixSize ; idx ++) {
80+ final int elA = rowA [idx ];
81+ final int [] rowB = matrixB [idx ];
82+ for (int col = 0 ; col < matrixSize ; col ++) {
83+ rowC [col ] += elA * rowB [col ];
84+ }
85+ }
86+ latch .countDown ();
87+ });
88+ }
89+ latch .await ();
90+ return matrixC ;
91+ }
92+
16593 public static int [][] singleThreadMultiplyOpt (int [][] matrixA , int [][] matrixB ) {
16694 final int matrixSize = matrixA .length ;
16795 final int [][] matrixC = new int [matrixSize ][matrixSize ];
@@ -184,6 +112,25 @@ public static int[][] singleThreadMultiplyOpt(int[][] matrixA, int[][] matrixB)
184112 return matrixC ;
185113 }
186114
115+ public static int [][] singleThreadMultiplyOpt2 (int [][] matrixA , int [][] matrixB ) {
116+ final int matrixSize = matrixA .length ;
117+ final int [][] matrixC = new int [matrixSize ][matrixSize ];
118+
119+ for (int row = 0 ; row < matrixSize ; row ++) {
120+ final int [] rowA = matrixA [row ];
121+ final int [] rowC = matrixC [row ];
122+
123+ for (int idx = 0 ; idx < matrixSize ; idx ++) {
124+ final int elA = rowA [idx ];
125+ final int [] rowB = matrixB [idx ];
126+ for (int col = 0 ; col < matrixSize ; col ++) {
127+ rowC [col ] += elA * rowB [col ];
128+ }
129+ }
130+ }
131+ return matrixC ;
132+ }
133+
187134 public static int [][] create (int size ) {
188135 int [][] matrix = new int [size ][size ];
189136 Random rn = new Random ();
0 commit comments