Skip to content

Commit 61fa53e

Browse files
committed
2_3_HW1_concurrentMultiply2
1 parent efeec67 commit 61fa53e

2 files changed

Lines changed: 63 additions & 120 deletions

File tree

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

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,6 @@
44
import java.util.concurrent.ExecutorService;
55
import java.util.concurrent.Executors;
66

7-
/**
8-
* gkislin
9-
* 03.07.2016
10-
*/
117
public class MainMatrix {
128
private static final int MATRIX_SIZE = 1000;
139
private static final int THREAD_NUMBER = 10;
@@ -30,7 +26,7 @@ public static void main(String[] args) throws ExecutionException, InterruptedExc
3026
singleThreadSum += duration;
3127

3228
start = System.currentTimeMillis();
33-
final int[][] concurrentMatrixC = MatrixUtil.concurrentMultiply(matrixA, matrixB, executor);
29+
final int[][] concurrentMatrixC = MatrixUtil.concurrentMultiplyStreams(matrixA, matrixB, Runtime.getRuntime().availableProcessors() - 1);
3430
duration = (System.currentTimeMillis() - start) / 1000.;
3531
out("Concurrent thread time, sec: %.3f", duration);
3632
concurrentThreadSum += duration;

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

Lines changed: 62 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -1,134 +1,39 @@
11
package ru.javaops.masterjava.matrix;
22

3-
import java.util.*;
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
import java.util.Random;
46
import java.util.concurrent.*;
5-
import java.util.stream.Collectors;
67
import java.util.stream.IntStream;
78

8-
/**
9-
* gkislin
10-
* 03.07.2016
11-
*/
129
public 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

Comments
 (0)