Skip to content

Commit 79b6c0c

Browse files
committed
2_02_HW1_concurrentMultiply.patch
1 parent 870c9b1 commit 79b6c0c

1 file changed

Lines changed: 148 additions & 5 deletions

File tree

src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java

Lines changed: 148 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,163 @@
11
package 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
*/
1112
public 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

Comments
 (0)