11package ru .javaops .masterjava .matrix ;
22
3- import java .util .Random ;
4- import java .util .concurrent .ExecutionException ;
5- import java .util .concurrent .ExecutorService ;
3+ import java .util .*;
4+ import java .util .concurrent .*;
5+ import java .util .stream .Collectors ;
6+ import java .util .stream .IntStream ;
67
78/**
89 * gkislin
910 * 03.07.2016
1011 */
1112public class MatrixUtil {
1213
13- // TODO implement parallel multiplication matrixA*matrixB
1414 public static int [][] concurrentMultiply (int [][] matrixA , int [][] matrixB , ExecutorService executor ) throws InterruptedException , ExecutionException {
1515 final int matrixSize = matrixA .length ;
1616 final int [][] matrixC = new int [matrixSize ][matrixSize ];
1717
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 )
99+ throws InterruptedException , ExecutionException {
100+
101+ final int matrixSize = matrixA .length ;
102+ final int [][] matrixC = new int [matrixSize ][matrixSize ];
103+
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 ];
119+ }
120+ matrixC [j ][i ] = sum ;
121+ }
122+ return null ;
123+ }
124+ })
125+ .collect (Collectors .toList ());
126+
127+ executor .invokeAll (tasks );
128+ return matrixC ;
129+ }
130+
131+ public static int [][] concurrentMultiply2 (int [][] matrixA , int [][] matrixB , ExecutorService executor ) throws InterruptedException , ExecutionException {
132+ final int matrixSize = matrixA .length ;
133+ final int [][] matrixC = new int [matrixSize ][];
134+
135+ final int [][] matrixBT = new int [matrixSize ][matrixSize ];
136+ for (int i = 0 ; i < matrixSize ; i ++) {
137+ for (int j = 0 ; j < matrixSize ; j ++) {
138+ matrixBT [i ][j ] = matrixB [j ][i ];
139+ }
140+ }
141+
142+ List <Callable <Void >> tasks = new ArrayList <>(matrixSize );
143+ for (int j = 0 ; j < matrixSize ; j ++) {
144+ final int row = j ;
145+ tasks .add (() -> {
146+ final int [] rowC = new int [matrixSize ];
147+ for (int col = 0 ; col < matrixSize ; col ++) {
148+ final int [] rowA = matrixA [row ];
149+ final int [] columnB = matrixBT [col ];
150+ int sum = 0 ;
151+ for (int k = 0 ; k < matrixSize ; k ++) {
152+ sum += rowA [k ] * columnB [k ];
153+ }
154+ rowC [col ] = sum ;
155+ }
156+ matrixC [row ] = rowC ;
157+ return null ;
158+ });
159+ }
160+ executor .invokeAll (tasks );
18161 return matrixC ;
19162 }
20163
@@ -64,4 +207,4 @@ public static boolean compare(int[][] matrixA, int[][] matrixB) {
64207 }
65208 return true ;
66209 }
67- }
210+ }
0 commit comments