121 lines
3.9 KiB
Java
121 lines
3.9 KiB
Java
import java.util.ArrayList;
|
||
import java.util.Arrays;
|
||
import java.util.Comparator;
|
||
import java.util.List;
|
||
import java.util.concurrent.ExecutorService;
|
||
import java.util.concurrent.Executors;
|
||
import java.util.concurrent.TimeUnit;
|
||
|
||
public class MatrixMultiplier {
|
||
private final int[][] matrixA;
|
||
private final int[][] matrixB;
|
||
private final int[][] result;
|
||
private final int size;
|
||
|
||
public MatrixMultiplier(int size) {
|
||
this.size = size;
|
||
this.matrixA = generateMatrix(size);
|
||
this.matrixB = generateMatrix(size);
|
||
this.result = new int[size][size];
|
||
}
|
||
|
||
private int[][] generateMatrix(int size) {
|
||
int[][] matrix = new int[size][size];
|
||
for (int i = 0; i < size; i++) {
|
||
for (int j = 0; j < size; j++) {
|
||
matrix[i][j] = (int) (Math.random() * 10);
|
||
}
|
||
}
|
||
return matrix;
|
||
}
|
||
|
||
public void multiplySequential() {
|
||
for (int i = 0; i < size; i++) {
|
||
for (int j = 0; j < size; j++) {
|
||
for (int k = 0; k < size; k++) {
|
||
result[i][j] += matrixA[i][k] * matrixB[k][j];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
public void multiplyParallel(int numThreads) throws InterruptedException {
|
||
if (numThreads == 1) {
|
||
multiplySequential();
|
||
return;
|
||
}
|
||
|
||
ExecutorService executor = Executors.newFixedThreadPool(numThreads);
|
||
int chunkSize = (int) Math.ceil((double) size / numThreads);
|
||
|
||
for (int thread = 0; thread < numThreads; thread++) {
|
||
final int startRow = thread * chunkSize;
|
||
final int endRow = Math.min(startRow + chunkSize, size);
|
||
|
||
executor.submit(() -> {
|
||
for (int i = startRow; i < endRow; i++) {
|
||
for (int j = 0; j < size; j++) {
|
||
for (int k = 0; k < size; k++) {
|
||
result[i][j] += matrixA[i][k] * matrixB[k][j];
|
||
}
|
||
}
|
||
}
|
||
});
|
||
}
|
||
executor.shutdown();
|
||
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
|
||
}
|
||
|
||
private void resetResult() {
|
||
for (int i = 0; i < size; i++) {
|
||
Arrays.fill(result[i], 0);
|
||
}
|
||
}
|
||
|
||
static class Result {
|
||
int threads;
|
||
long time;
|
||
|
||
Result(int threads, long time) {
|
||
this.threads = threads;
|
||
this.time = time;
|
||
}
|
||
}
|
||
|
||
public static void main(String[] args) throws InterruptedException {
|
||
int[] matrixSizes = {100, 300, 500};
|
||
int[] threadCounts = {1, 2, 4, 6, 8, 10};
|
||
int runs = 5; // количество прогонов
|
||
|
||
for (int size : matrixSizes) {
|
||
System.out.println("\nРазмер матрицы: " + size + "x" + size);
|
||
MatrixMultiplier multiplier = new MatrixMultiplier(size);
|
||
List<Result> results = new ArrayList<>();
|
||
|
||
for (int threads : threadCounts) {
|
||
long totalDuration = 0;
|
||
|
||
for (int run = 0; run < runs; run++) {
|
||
multiplier.resetResult();
|
||
long startTime = System.nanoTime();
|
||
multiplier.multiplyParallel(threads);
|
||
long endTime = System.nanoTime();
|
||
|
||
totalDuration += (endTime - startTime);
|
||
}
|
||
|
||
long averageDuration = totalDuration / runs;
|
||
results.add(new Result(threads, averageDuration));
|
||
}
|
||
|
||
// Сортировка по времени выполнения
|
||
results.sort(Comparator.comparingLong(r -> r.time));
|
||
|
||
System.out.println("Результаты (среднее время за " + runs + " прогонов):");
|
||
for (Result result : results) {
|
||
System.out.printf("Потоки: %d, среднее время: %d нс\n", result.threads, result.time);
|
||
}
|
||
}
|
||
}
|
||
}
|