我對並行化完全陌生。我想平行嵌套for循環並存儲一些中間結果。結果來自一個函數f,它取自一些形式參數和一些來自全局變量的值。我從here得到了一些建議,例如我使用itertools來生成相當於嵌套循環的笛卡爾積。但它似乎並不奏效。我想要存儲中間結果的數組保持不變。附上最簡單的工作示例。試圖平行嵌套的for循環並保存中間結果
操作系統:Windows 7 64位
Python發行:天幕Enthought
import itertools
import numpy as np
from multiprocessing import Pool
list1 = range(4, 8)
list2 = range(6, 9)
ary = np.zeros((len(list1), len(list2)))
#This is the archetypical function f. It DOES NOT have p2 as a parameter! This
#is intended! In my (more complex) program a function f calls somewhere deep
#down another function that gets its values from global variables. Rewriting
#the code to hand down the variables as parameters would turn my code into a mess.
def f(p1):
return p1*p2
#This is what I want to parallelize: a nested loop, where the result of f is saved
#in an array element corresponding to the indices of p1 and p2.
#for p1 in list1:
# for p2 in list2:
# i = list1.index(p1)
# j = list2.index(p2)
# ary[i,j]=f(p1)
#Here begins the try to parallelize the nested loop. The function g calls f and
#does the saving of the results. g takes a tuple x, unpacks it, then calculates
#f and saves the result in an array.
def g(x):
a, b = x
i = list1.index(a)
j = list2.index(b)
global p2
p2 = b
ary[i,j] = f(a)
if __name__ == "__main__":
#Produces a cartesian product. This is equivalent to a nested loop.
it = itertools.product(list1, list2)
pool = Pool(processes=2)
result = pool.map(g, it)
print ary
#Result: ary does not change!
好的,你說我不應該依賴ary的「全局性」。好,我在g()ary [i,j] = f(a)的定義中用 'return(i,j,f(a))替換' 然後結果不包含'None',我可以構造從結果ary。我定義了一個函數 'def constr(x): i,j,val = x ary [i,j] = val' 然後我可以將結構映射到結果上並得到ary。有用!謝謝!關於全局性:是否可以導致競爭條件,即一個進程獲得p2的'錯誤'值,因爲另一個進程更改了其(全局值)?p2 p2 = b' – hauntergeist
@David:如果你接受我的回答,會很好。對你的評論:我想,這不會發生,但是,再次,有一個'全球',試圖重寫。 – spiehr
我做了一個測試:我在代碼的開頭設置了p2 = 0。然後執行並行部分。 ary被正確構建,並且p2的(全局)值保持爲0.我想每個進程都會得到list1,list2,ary,p2等的副本,並且可以在不修改原始進程或其他進程的副本的情況下對其進行修改。它似乎工作,但對我來說仍然有點神奇。我不能在沒有'全局'的情況下重寫我的真實代碼,因爲需要這些全局值的函數嵌套在其他函數中。重寫現有的代碼將是一場超越其好處的噩夢。 – hauntergeist