Я пытаюсь использовать multiprocess
в Python 3 для преобразования цикла for в параллельный цикл for в Windows
.Подвох заключается в том, что обрабатываемые массивы должны иметь общую память, потому что в противном случае у меня закончится память.Как я могу распараллелить код внизу этого сообщения?
Вызов bigExampleArray = multiprocessing.Array(bigExampleArray)
должен преобразовать его в массив с общей памятью для многопроцессорной обработки, насколько я понял.И я рассмотрел несколько примеров, которые все полагаются на создание определений функций для параллельной работы, но я не уверен, как передать все, что мне нужно, в функцию, когда я вызываю ее, используя один из множества * 1006.* методы.Например:
p = multiprocessing.Process(target=parallelForLoopFun, args=(bigExampleArray, bigChangingArray));
p.start();
или
p = multiprocessing.Pool(4);
p.map(parallelForLoopFun, someConstantArray?);
Я не вижу способа отправить то, что я хочу, с помощью iCntr, с вышеуказанными способами вызова параллельных рабочих функций - или свызов карты, как легко отправлять несколько многомерных массивов.
Я пробовал пакет numba
с @jit
(примененным до определения в функции) и range
-> prange
, но этоне смог ускорить мой более сложный код.(Используйте from numba import jit, prange
, чтобы импортировать его, если вы еще не пробовали numba)
В идеале я хотел бы иметь возможность преобразовать цикл for в параллель цикла for с помощью простого вызова range
->prange
- но если требуется отдельная функция, в идеале это должно быть что-то вроде:
def parallelForLoopFun(iCntr,bigExampleArray,bigChangingArray)
if( bigExampleArray[iCntr,2] > 0.5 ):
temporaryNumber = np.int32(11+iCntr);
else:
temporaryNumber = np.int32(1+iCntr);
bigChangingArray[iCntr,:] = np.array( [bigExampleArray[iCntr,1],bigExampleArray[iCntr,2]+temporaryNumber] );
Для подготовки примеров массивов этот код должен работать:
import numpy as np
import time
from test_fun import tediusConverter #I named the function file test_fun
bigExampleArray = np.random.rand(100000000,3);
tic = time.time(); #for time testing
bigReturnedArray = tediusConverter(bigExampleArray);
toc = time.time() - tic; #for time testing
print("\nTime to run: {} sec\n".format(toc)); #extra space at end
Ниже приведенофункция, которую я хотел бы распараллелить:
import numpy as np
def tediusConverter(bigExampleArray):
bigChangingArray = np.zeros( (len(bigExampleArray[:,0]) , 2 ) ); #preallocate
for iCntr in range(0, len(bigExampleArray[:,0])):
if( bigExampleArray[iCntr,2] > 0.5 ):
temporaryNumber = np.int32(11+iCntr);
else:
temporaryNumber = np.int32(1+iCntr);
bigChangingArray[iCntr,:] = np.array( [bigExampleArray[iCntr,1],bigExampleArray[iCntr,2]+temporaryNumber] );
return bigChangingArray;
Приведенный выше код является обобщением, чтобы облегчить (надеюсь) понимание и применение к другим вещам.На моем 4C i5-4960k с частотой 4,5 ГГц вышеупомянутый процесс занимает ~ 205 секунд.Наконец, обратите внимание, что numba
@jit(nopython=False,parallel=True)
и range
-> prange
могут работать с этим упрощенным кодом и видеть время выполнения ~ 12 секунд и использовать ~ 100% ЦП - так что естьнадеюсь!(nopython=True
также работает при времени выполнения ~ 8 секунд ...)