2014-02-22 43 views
1

我有一個目前正在運行的模擬,但ETA大概是40個小時 - 我試圖通過多處理加速它。具有單一功能的Python多重處理

它基本上迭代一個變量(L)的3個值和第二個變量(a)的99個值。使用這些值,它本質上運行一個複雜的模擬並返回9個不同的標準偏差。因此(即使我還沒有這樣編碼),它本質上是一個函數,它將兩個值作爲輸入(L,a)並返回9個值。

這裏是代碼的精髓,我有:

STD_1 = [] 
STD_2 = [] 
# etc. 

for L in range(0,6,2): 
    for a in range(1,100): 
     ### simulation code ### 
     STD_1.append(value_1) 
     STD_2.append(value_2) 
     # etc. 

這是我可以將它修改爲:

master_list = [] 

def simulate(a,L): 
    ### simulation code ### 
    return (a,L,STD_1, STD_2 etc.) 

for L in range(0,6,2): 
    for a in range(1,100): 
     master_list.append(simulate(a,L)) 

由於每個模擬的是獨立的,這似乎是一個理想的實現某種多線程/處理。

我到底該如何編碼?

編輯:此外,將所有內容按順序返回到主列表,或者如果多個進程正在工作,可能會出現故障嗎?

編輯2:這是我的代碼 - 但它無法正確運行。它詢問我是否想在運行它後立即殺死程序。

import multiprocessing 

data = [] 

for L in range(0,6,2): 
    for a in range(1,100): 
     data.append((L,a)) 

print (data) 

def simulation(arg): 
    # unpack the tuple 
    a = arg[1] 
    L = arg[0] 
    STD_1 = a**2 
    STD_2 = a**3 
    STD_3 = a**4 
    # simulation code # 
    return((STD_1,STD_2,STD_3)) 

print("1") 

p = multiprocessing.Pool() 

print ("2") 

results = p.map(simulation, data) 

編輯3:還有什麼是多處理的限制。我聽說它在OS X上不起作用,這是否正確?

+0

我通常會做這樣的事情的方法是在你創建的所有可能的,其中循環使用'Pool.apply_async'就在那裏參數。然後在循環結束時,將'p.close();頁。加入()'然後等待;-) –

回答

1
  • 將每次迭代的數據包裝到一個元組中。
  • 讓那些元組
  • 列表data寫一個函數f處理一個元組,並返回一個結果
  • 創建p = multiprocessing.Pool()對象。
  • 呼叫results = p.map(f, data)

你的機器具有獨立的進程核心這將運行的f的多個實例。

EDIT1:示例:

from multiprocessing import Pool 

data = [('bla', 1, 3, 7), ('spam', 12, 4, 8), ('eggs', 17, 1, 3)] 

def f(t): 
    name, a, b, c = t 
    return (name, a + b + c) 

p = Pool() 
results = p.map(f, data) 
print results 

EDIT2:

多重應該工作在類UNIX平臺細如OSX。只有缺少os.fork(主要是MS Windows)的平臺需要特別關注。但即使如此,它仍然有效。請參閱多處理文檔。

+0

感謝您的回覆。你可以把你的建議放到一個可以運行的代碼塊中,讓它對我來說更清楚些嗎?我對Python仍然很陌生,並且有一個與我的情況完全相符的簡單示例會很有幫助! –

+0

@ user264087:查看更新的答案。 –

+0

在我的電腦上,這段代碼無限期地掛起。我在OS X上運行Python 3.3.3。 –

0

這裏是並行的線程運行的一種方式:

import threading 

L_a = [] 

for L in range(0,6,2): 
    for a in range(1,100): 
     L_a.append((L,a)) 
     # Add the rest of your objects here 

def RunParallelThreads(): 
    # Create an index list 
    indexes = range(0,len(L_a)) 
    # Create the output list 
    output = [None for i in indexes] 
    # Create all the parallel threads 
    threads = [threading.Thread(target=simulate,args=(output,i)) for i in indexes] 
    # Start all the parallel threads 
    for thread in threads: thread.start() 
    # Wait for all the parallel threads to complete 
    for thread in threads: thread.join() 
    # Return the output list 
    return output 

def simulate(list,index): 
    (L,a) = L_a[index] 
    list[index] = (a,L) # Add the rest of your objects here 

master_list = RunParallelThreads() 
+0

在過去幾天我所做的閱讀中,人們已經指出線程不如多處理。我在某處看到,使用線程實際上需要的時間比串行過程要長。這是真的? –

+0

不確定。我記得一位朋友告訴我,Python中的多線程是由Python解釋器模擬的,而不是由操作系統作爲「真正」的並行線程來執行。 –

+0

無論如何,上面的代碼都會運行。因此,您可以簡單地添加剩餘的對象,並將性能與順序代碼的性能進行比較。 –