Merge pull request 'afanasev_dmitry_lab_5 is ready' (#173) from afanasev_dmitry_lab_5 into main
Reviewed-on: #173
This commit is contained in:
commit
e01e3267c6
31
afanasev_dmitry_lab_5/README.md
Normal file
31
afanasev_dmitry_lab_5/README.md
Normal file
@ -0,0 +1,31 @@
|
||||
# Лабораторная работа 5
|
||||
|
||||
## Описание
|
||||
Задание заключается в реализации алгоритмов умножения больших квадратных матриц. Необходимо разработать два алгоритма: последовательный и параллельный. А также провести бенчмарки, а затем описать результаты в отчете.
|
||||
|
||||
**100x100 матрица**:
|
||||
- **4 потока** — наилучший результат.
|
||||
- **10 потоков** — медленнее на почти в половину.
|
||||
- **6 и 8 потоков** — хуже 4 потоков.
|
||||
- **1 и 2 потока** — значительно медленнее.
|
||||
|
||||
**300x300 матрица**:
|
||||
- **4 потока** — лучший результат.
|
||||
- **8 потоков** — чуть хуже.
|
||||
- **10 потоков** — медленнее.
|
||||
- **1 и 2 потока** — значительно медленнее.
|
||||
|
||||
**500x500 матрица**:
|
||||
- **8 потоков** — лучший результат.
|
||||
- **6 и 10 потоков** — немного хуже.
|
||||
- **4 потока** — значительно медленнее.
|
||||
- **1 поток** — самый медленный.
|
||||
|
||||
**Ссылка на демонстрацию работы программы**: https://vk.com/video215756667_456239455?list=ln-z7zFcpvxLexJd3f8ss
|
||||
|
||||
**Вывод**:
|
||||
- Если операция сложнее, рост производительности происходит с увеличением числа потоков.
|
||||
- Слишком много потоков увеличивает накладные расходы (например, 10 потоков). Это может быть связано, например, с:
|
||||
1. **Переключением контекстов**: Когда потоков больше, чем ядер процессора, операционная система часто переключает контексты, что занимает время.
|
||||
2. **Конкуренцией за ресурсы**: Много потоков конкурируют за ограниченные ресурсы, такие как процессорное время и кэш.
|
||||
3. **Управлением потоками**: С увеличением числа потоков растёт нагрузка на систему, связанную с их созданием, управлением и завершением.
|
29
afanasev_dmitry_lab_5/main/.gitignore
vendored
Normal file
29
afanasev_dmitry_lab_5/main/.gitignore
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
### IntelliJ IDEA ###
|
||||
out/
|
||||
!**/src/main/**/out/
|
||||
!**/src/test/**/out/
|
||||
|
||||
### Eclipse ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
bin/
|
||||
!**/src/main/**/bin/
|
||||
!**/src/test/**/bin/
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
|
||||
### Mac OS ###
|
||||
.DS_Store
|
120
afanasev_dmitry_lab_5/main/src/MatrixMultiplier.java
Normal file
120
afanasev_dmitry_lab_5/main/src/MatrixMultiplier.java
Normal file
@ -0,0 +1,120 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user