Как управлять областью, используя многопроцессорность - PullRequest
0 голосов
/ 14 февраля 2019

Я пытаюсь реализовать функцию, которая использует python multiprocessing для ускорения вычислений.Я пытаюсь создать матрицу попарных расстояний, но реализация цикла for занимает более 8 часов.

Этот код работает быстрее, но при печати матрица полна нулей.Когда я печатаю строки в функции, кажется, работает.Я думаю, что это проблема масштаба, но я не могу понять, как с ней бороться.

import multiprocessing
import time
import numpy as np

def MultiProcessedFunc(i,x):
    for j in range(i,len(x)):
        time.sleep(0.08)
        M[i,j] = (x[i]+x[j])/2
    print(M[i,:]) # Check if the operation works
    print('')

processes = []

v = [x+1 for x in range(8000)]
M = np.zeros((len(v),len(v)))

for i in range(len(v)):
    p = multiprocessing.Process(target = MultiProcessedFunc, args =(i,v))
    processes.append(p)
    p.start()

for process in processes:
    process.join()
end = time.time()

print('Multiprocessing: {}'.format(end-start))
print(M)

1 Ответ

0 голосов
/ 14 февраля 2019

К сожалению, ваш код не будет работать таким образом.Многопроцессорное порождение отдельных процессов , что означает, что пространство памяти разделено !Изменения, сделанные одним подпроцессом, не будут отражены в других процессах или ваших родительских процессах.

Строго говоря, это не ограниченная проблема.Область действия - это нечто, определенное внутри одного процесса интерпретатора.

Модуль предоставляет средства совместного использования памяти между процессами , но это обходится дорого (общая память работает медленнее из-за проблем с блокировкой и тому подобного)..

Теперь у numpy есть приятная особенность: он освобождает GIL во время вычисления . Это означает, что использование multi threading вместо multiprocessing должно дать вамнекоторые преимущества с небольшими другими изменениями в вашем коде, просто замените import multiprocessing на import threading и multiprocessing.Process на threading.Thread. Код должен дать правильный результат. На моей машине удаляются операторы печати и код sleepон запускается менее чем за 8 секунд:

Multiprocessing: 7.48570203781
[[1.000e+00 1.000e+00 2.000e+00 ... 3.999e+03 4.000e+03 4.000e+03]
 [0.000e+00 2.000e+00 2.000e+00 ... 4.000e+03 4.000e+03 4.001e+03]
 [0.000e+00 0.000e+00 3.000e+00 ... 4.000e+03 4.001e+03 4.001e+03]
 ...
 [0.000e+00 0.000e+00 0.000e+00 ... 7.998e+03 7.998e+03 7.999e+03]
 [0.000e+00 0.000e+00 0.000e+00 ... 0.000e+00 7.999e+03 7.999e+03]
 [0.000e+00 0.000e+00 0.000e+00 ... 0.000e+00 0.000e+00 8.000e+03]]

В качестве альтернативы можно указать, что ваши подпроцессы возвращают результат, а затем объединяют результаты в основном процессе.

...