Научиться использовать многопроцессность как основу параллельного программирования с помощью модуля multiprocessing
- Написать программу, перемножающую две матрицы поэлементно. Элементы матрицы-произведения должны вычисляться в несколько потоков.
- Программа должна читать две матрицы из исходных файлов. Матрица-произведение также должна записываться в файл.
- Используйте пул процессов, чтобы распределять вычисления между определенным заранее количеством процессов, не зависящим от размеров матрицы.
- Модифицируйте программу, чтобы элементы результирующей матрицы записывались в промежуточный файл сразу по факту их вычисления.
Довольно часто при решении прикладных задач приходится выполнять тяжелые математические расчеты. Такие расчеты могут занимать много времени и естественно желание ускорить работу программы, распараллелив вычисления на несколько ядер процессора. Точно такой же подход используется и в высокопроизводительных системах при распараллеливании несколько узлов вычислительного кластера.
Для начала нужно понять, какой аспект этой задачи можно распараллеливать. При перемножении матриц для вычисления определенного элемента совершенно не обязательно знать результат вычисления других элементов. Поэтому, каждый элемент можно вычислить независимо от других.
Для того, чтобы выделить участок кода в поток, выделим его в функцию. То есть, нам надо написать функцию, которая вычисляет один определенный элемент матрицы. Для этого необходимо знать индекс этого элемента, и исходные матрицы:
def element(index, A, B, res):
glodal res
i, j = index
res = 0
# get a middle dimension
N = len(A[0]) or len(B)
for k in range(N):
res += A[i][k] * B[k][j]
return res
Для использования многопроцессности необходимо импортировать соответствующий модуль:
from multiprocessing import Process, Pool
Теперь мы можем создать новый процесс и запустить в нем вычисление отдельного элемента матрицы.
res = 0
p1 = Process(target=element, args=[(0, 0), matrix1, matrix2, res])
p1.start()
p1.join()
print(res)
Осталось только придумать легкий способ запустить на выполнение вычисление всех элементов матрицы.
- Модифицируйте программу таким образом, чтобы она сама определяла количество необходимых параллельных потоков.
- Модифицируйте программу таким образом, чтобы одна часть программы генерировала случайные квадратные матрицы заданной размерности, а другая - перемножала их по мере генерации. Протестируйте асинхронность работы программы. Реализуйте механизм остановки процесса перемножения.