Files
SSPR_25/kukushkina_ekaterina_lab_1
2025-03-14 12:52:04 +04:00
..
2025-03-14 12:52:04 +04:00
2025-03-14 12:52:04 +04:00

Лабораторная работа №1. Вариант 12.

Задание: определить среднее арифметическое элементов матрицы ниже главной диагонали.

Как запустить лабораторную работу?

Чтобы её запустить нам потребуется:

  • Сомпилировать файл с кодом в формате java с помощью комманды: javac Main.java
  • Запустить программу с помощью команды: java Main

Какие технологии использовали?

Используемые технологии:

  • java.io.*: Для операций ввода-вывода, таких как чтение и запись файлов.
  • java.util.*: Содержит основные классы коллекций (List, ArrayList, Scanner и т.д.) и другие утилиты.
  • java.util.concurrent.*: Предоставляет инструменты для многопоточного программирования, включая ExecutorService, ThreadPoolExecutor, Future, Callable, ForkJoinPool и другие. ThreadPoolExecutor: Управляет пулом потоков фиксированного размера для параллельного выполнения задач, отправляемых в очередь. ForkJoinPool: Реализует "кражу работы" (work-stealing) для эффективного параллельного выполнения рекурсивно разделяемых задач.

Что программа делает?

Данная программа вычисляет среднее арифметическое элементов ниже главной диагонали квадратной матрицы, сравнивая однопоточный и два многопоточных подхода: ThreadPoolExecutor и ForkJoinPool. Пользователь вводит размер матрицы, она генерируется, сохраняется в файл, считывается обратно, а затем для каждого алгоритма измеряется время выполнения и выводится результат. Программа обрабатывает некорректный ввод пользователя и завершает работу с ошибкой. Цель: продемонстрировать преимущества многопоточности в решении данной вычислительной задачи и сравнить производительность различных способов распараллеливания.

Примеры входных и выходных значений.

Введите размер матрицы (квадратной): 1000
Однопоточный алгоритм: 4 мс, Среднее арифметическое: 99.49616216216216
Многопоточный алгоритм с использованием ThreadPoolExecutor: 58 мс, Среднее арифметическое: 99.49616216216216
Многопоточный алгоритм с использованием ForkJoinPool: 9 мс, Среднее арифметическое: 99.49616216216216\

Введите размер матрицы (квадратной): 5000
Однопоточный алгоритм: 90 мс, Среднее арифметическое: 99.5001852370474
Многопоточный алгоритм с использованием ThreadPoolExecutor: 202 мс, Среднее арифметическое: 99.5001852370474
Многопоточный алгоритм с использованием ForkJoinPool: 68 мс, Среднее арифметическое: 99.5001852370474\

Введите размер матрицы (квадратной): 9000
Однопоточный алгоритм: 312 мс, Среднее арифметическое: 99.48965727056093
Многопоточный алгоритм с использованием ThreadPoolExecutor: 378 мс, Среднее арифметическое: 99.48965727056093
Многопоточный алгоритм с использованием ForkJoinPool: 113 мс, Среднее арифметическое: 99.48965727056093\

Введите размер матрицы (квадратной): 12000
Однопоточный алгоритм: 650 мс, Среднее арифметическое: 99.4960964941523
Многопоточный алгоритм с использованием ThreadPoolExecutor: 607 мс, Среднее арифметическое: 99.4960964941523
Многопоточный алгоритм с использованием ForkJoinPool: 207 мс, Среднее арифметическое: 99.4960964941523\

Введите размер матрицы (квадратной): 14000
Однопоточный алгоритм: 8901 мс, Среднее арифметическое: 99.50303716592002
Многопоточный алгоритм с использованием ThreadPoolExecutor: 1280 мс, Среднее арифметическое: 99.50303716592002
Многопоточный алгоритм с использованием ForkJoinPool: 142 мс, Среднее арифметическое: 99.50303716592002\

Вывод по полученным результатам.

Иссходя из полученных результатов мы можем сделать вывод, что чем больше объём входных данных тем более выгодно использовать многопоточность для реализации алгоритмов. Объясняется это тем, что чем больше объем входных данных, тем больше работы можно параллельно распределить между потоками, минимизируя время простоя и максимально используя ресурсы процессора, что приводит к значительному ускорению выполнения алгоритма по сравнению с однопоточным решением.
В данном варианте метод с использованием ThreadPoolExecutor показывает себя не очень эффективно, становясь быстрее однопоточного алгоритма только на очень больших размерах матрицы. Происходит это если задача занимает мало времени, и накладные расходы на создание задачи, переключение контекста между потоками и синхронизацию могут превысить выигрыш от распараллеливания, делая однопоточное решение более эффективным.