Я пытаюсь оптимизировать свой код с помощью модуля Python multiprocessing.Pool
, но я не получаю результаты ускорения, которые я бы логически ожидал.Многопроцессорность Python не дает ожидаемого ускорения
Основной метод, который я делаю, включает вычисление продуктов матричного вектора для большого числа векторов и фиксированной большой разреженной матрицы. Ниже приведен пример игрушки, который выполняет то, что мне нужно, но со случайными матрицами.
import time
import numpy as np
import scipy.sparse as sp
def calculate(vector, matrix = None):
for i in range(50):
v = matrix.dot(vector)
return v
if __name__ == '__main__':
N = 1e6
matrix = sp.rand(N, N, density = 1e-5, format = 'csr')
t = time.time()
res = []
for i in range(10):
res.append(calculate(np.random.rand(N), matrix = matrix))
print time.time() - t
Способ заканчивается примерно 30
секунд.
Теперь, поскольку расчет каждого элемента results
не зависит от результатов каких-либо других вычислений, естественно предположить, что вычисление паралелей ускорит процесс. Идея состоит в том, чтобы создать 4 процесса, и если каждый из них выполняет некоторые вычисления, то время, необходимое для завершения всех процессов, должно уменьшаться примерно на 4
. Для этого я написал следующий код:
import time
import numpy as np
import scipy.sparse as sp
from multiprocessing import Pool
from functools import partial
def calculate(vector, matrix = None):
for i in range(50):
v = matrix.dot(vector)
return v
if __name__ == '__main__':
N = 1e6
matrix = sp.rand(N, N, density = 1e-5, format = 'csr')
t = time.time()
input = []
for i in range(10):
input.append(np.random.rand(N))
mp = partial(calculate, matrix = matrix)
p = Pool(4)
res = p.map(mp, input)
print time.time() - t
Моя проблема заключается в том, что этот код занимает немного выше 20
секунд для запуска, так что я даже не повысить производительность за счет фактора 2
! Хуже того, производительность не улучшается, даже если в пуле есть 8
процессов! Любая идея, почему ускорение не происходит?
Примечание: Мой фактический метод занимает гораздо больше времени, а входные векторы сохраняются в файле. Если я разделяю файл на 4
штук, а затем запускаю мой сценарий в отдельном процессе для каждого файла вручную, каждый процесс завершается в четыре раза быстрее, чем для всего файла (как и ожидалось). Я confuzed почему эта скорость вверх (что, очевидно, возможно) не происходит с multiprocessing.Pool
Эди: Я только что нашел Multiprocessing.Pool makes Numpy matrix multiplication slower этот вопрос, который может быть связан. Я должен проверить, хотя.
Вопрос: Сколько физических (не гипертекстовых) ядер процессора использует ли система, на которой вы работаете? –
@KlausD. Физически у меня есть «4» ядра. Вот почему я вручную разбил файл на '4', а не на' 8'. – 5xum
Если вы поставили контрольные значения 'time.time()' в свой метод 'calculate', вы увидите, что 50 вызовов' dot' занимают почти 4 раза дольше, чем в непараллельном случае. Мне непонятно, почему, потому что такие инструменты, как 'top', делают его непараллельным, используют только один процессор полностью, тогда как параллельный случай делает его похожим на то, что 4 процессора полностью используются. –