[英]directing subsets from a large database to different cpus in python
我編寫了一些Python代碼,它從大型數據庫中提取信息,對數據庫中的每個項目執行一些最大似然建模,然后存儲結果。 代碼可以串行工作,每個項目需要1-2秒。 問題是,我在數據庫中有幾百萬個項目,因此代碼的連續運行將花費數周時間。 我可以訪問一個擁有16個cpus的集群,我編寫了一個將初始輸入目錄分解為“塊”的函數,在每個塊上運行建模代碼,然后組織結果。 由於代碼建模部分的復雜性及其對第三方python軟件的依賴,我一直在嘗試使用多處理來並行化這些代碼,以便輸入目錄的每個塊都在一個單獨的cpu上運行。 目前,我嘗試產生的進程只能在一個cpu上運行。 有誰知道如何解決這一問題? 我是一名自學成才的科學程序員,所以我有一些使用Python的經驗,盡管這是我第一次嘗試並行化。 代碼太長了,無法在此完整顯示,但它基本上執行以下操作:
def split(a, n):
k, m = len(a) / n, len(a) % n
return (a[i * k + min(i, m):(i + 1) * k + min(i + 1, m)] for i in xrange(n))
ncpus = mp.cpu_count()
chunks = list(split(catlist, ncpus))
images = [im1, im2, im3, im4, im5, im6, im7, im8, im9, im10, im11, im12]
def process_chunks(chunk):
database_chunk = database[chunk[:]]
for i in range(0,len(database_chunk)):
# perform some analysis
for j in range(0,len(images)):
# perform more analysis
my_dict = {'out1': out1, 'out2':out2, 'out3': out3}
return my_dict
pool = mp.Pool(processes=ncpus)
result = [pool.apply(process_chunks, args=(chunks[id],)) for id in range(0,len(chunks))]
對於數據庫中只有13個項目的簡單測試示例,這就是塊看起來像(大致均勻分割列表的列表):
chunks = [[0,1,2,3],[4,5,6],[7,8,9],[10,11,12]]
代碼運行正常,pool.apply命令產生多個進程,但是所有進程都在一個cpu上運行,並且運行時沒有串行改進(事實上它有點慢,我想由於產生每個進程的開銷處理)。 有沒有辦法強制將每個進程分配給一個單獨的cpu,所以當我將它應用於完整數據庫(有數百萬項)時,我得到了一些改進? 或者也許是更好的解決這個問題的方法?
非常感謝你提前!
注意:如果它進一步澄清情況,我是一名天文學家,數據庫是一個包含超過一百萬條目的大型源目錄,圖像是12個不同波段的寬場馬賽克,我正在進行最大似然測光在每個來源的每個樂隊。
我一開始以為你遇到了全局解釋器鎖,但是你已經通過使用multiprocessing
避開它了。 值得慶幸的是,這意味着事情要比其他方面容易得多。 來自文檔 :
相當於apply()內置函數。 它會一直阻塞,直到結果准備就緒 ,因此apply_async()更適合並行執行工作。
(強調我的)
apply_async()
與apply()
API略有不同,但這是一個非常簡單的修改:
calculations = []
def reaper(result):
calculations.append(result)
for id in range(0, len(chunks)):
pool.apply_async(process_chunks, args=(chunks[id],), callback=reaper)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.