簡體   English   中英

將子集從大型數據庫引導到python中的不同cpu

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM