2016-03-26 7 views
2

Ich habe es mit einem Bildverarbeitungsproblem zu tun, das parallelisiert werden muss. Ich habe einige Beispiele gesehen, die die Verwendung von Parallelverarbeitung in Python zeigen, aber die Eingaben all dieser Beispiele sind 1-D-Arrays. Daher suche ich nach einer Möglichkeit, eine Funktion parallel zu machen, die zwei Prozesse auf einem Bild durchführt. Der folgende Code muss für die Parallelisierung verwendet werden:Wie kann ich diese Python for-Schleife parallelisieren?

for i in arange(0, shape(img)[0] - window_size[0], 10): 
    for j in arange(0, shape(img)[1] - window_size[1], 10): 
     Process1 = Do_something(img[i: i + winSize[0], j: j + winSize[1]]) 
     Process2 = Do_something(Process1) 

Wie kann diese verschachtelte Schleife parallelisiert werden?

+0

einen Blick auf diese: https://www.quora.com/What-is-the-Python-equivalent-of-MATLABs-parfor – Swier

Antwort

2

Ich bin nicht ganz sicher, was tut die Variablen bedeuten oder was tut die Do_something() Funktion tut, aber dies ist ein allgemeiner Weg, um es parallel zu machen:

import concurrent.futures 
import functools 

def process_stuff(i, j, img, winSize): 
    Process1 = Do_something(img[i: i + winSize[0], j: j + winSize[1]]) 
    Process2 = Do_something(Process1) 

with concurrent.futures.ProcessPoolExecutor() as executor: 
    for i in arange(0, shape(img)[0] - window_size[0], 10): 
     for j in arange(0, shape(img)[1] - window_size[1], 10): 
      executor.submit(process_stuff, i, j, img, winSize) 

Diese Lösung auf Python 3.2 und höher ausgestattet ist. Ältere Versionen können das multiprocessing Modul verwenden.

Wenn Sie für eine effizientere Art und Weise wollen damit auch die Rückgabewerte zu bekommen, ist dies ein weiterer Weg:

import concurrent.futures 
import functools 
import itertools 
import operator 

def process_stuff(i, j, img, winSize): 
    Process1 = Do_something(img[i: i + winSize[0], j: j + winSize[1]]) 
    Process2 = Do_something(Process1) 

with concurrent.futures.ProcessPoolExecutor() as executor: 
    i_iterator = arange(0, shape(img)[0] - window_size[0], 10) 
    j_iterator = arange(0, shape(img)[1] - window_size[1], 10) 
    product = itertools.product(i_iterator, j_iterator) 
    iter1, iter2 = itertools.tee(product) 
    i_iterator = map(operator.itemgetter(0), iter1) 
    j_iterator = map(operator.itemgetter(1), iter2) 

    do_process = functools.partial(process_stuff, img=img, winSize=winSize) 
    executor.map(do_process, i_iterator, j_iterator) 

Es ist ein bisschen komplizierter, aber was ich hier getan hat, ist die product() aller Kombinationen erhalten i und j, teilen i und j in zwei Iteratoren und map() mit den Iteratoren als Variablen.

UPDATE:

Meine beste Wette ist, dass das, was Sie auf die Übertragung des Bildes zu unterschiedlichen Prozessen zu halten. Dies wird nur den entsprechenden Teil des Bildes übertragen:

import concurrent.futures 
import itertools 

def process_stuff(img_part): 
    Process1 = Do_something(img_part) 
    Process2 = Do_something(Process1) 

with concurrent.futures.ProcessPoolExecutor() as executor: 
    i_iterator = arange(0, shape(img)[0] - window_size[0], 10) 
    j_iterator = arange(0, shape(img)[1] - window_size[1], 10) 
    product = itertools.product(i_iterator, j_iterator) 
    parts_generator = (img[i: i + winSize[0], j: j + winSize[1]] 
         for i, j in product) 

    executor.map(process_stuff, parts_generator) 
+0

Sie sollten wahrscheinlich eine Notiz hinzufügen, dass dies nur in Python 3.2 und höher funktioniert. –

+0

@Bharel, vielen Dank für die Zeit, die Sie genommen haben, um mir zu helfen. Ich habe beide Formen deiner Lösung benutzt. Obwohl alle Kerne nach dem Ausführen des Programms verwendet werden, ist die Zeit zum Erzielen der Ergebnisse wesentlich länger als die Einzelkernverarbeitung. Wo mache ich einen Fehler? Danke – Federico

+0

Danke @Federico :-) Ich habe eine dritte Lösung eingereicht. Es ist ein bisschen problematisch für mich zu wissen, welcher Teil des Codes die Zeit braucht. Wenn 'Do_something()' eine Funktion ist, die viel Zeit in Anspruch nimmt und parallel ausgeführt werden kann, verursacht die Übergabe der entsprechenden Bildteile an die Funktion nur einen geringen Transferaufwand und führt zu einer schnelleren Ausführung. – Bharel

Verwandte Themen