簡體   English   中英

Python:多核處理?

[英]Python: Multicore processing?

我一直在閱讀Python的多處理模塊 我仍然認為我對它能做什么沒有很好的理解。

假設我有一個四核處理器,我有一個包含1,000,000個整數的列表,我想要所有整數的總和。 我可以這樣做:

list_sum = sum(my_list)

但這只會將其發送到一個核心。

是否有可能使用多處理模塊將數組分開並讓每個核心得到它的部分之和並返回值,以便計算總和?

就像是:

core1_sum = sum(my_list[0:500000])          #goes to core 1
core2_sum = sum(my_list[500001:1000000])    #goes to core 2
all_core_sum = core1_sum + core2_sum        #core 3 does final computation

任何幫助,將不勝感激。

是的,可以對多個進程進行總結,非常類似於使用多個線程:

from multiprocessing import Process, Queue

def do_sum(q,l):
    q.put(sum(l))

def main():
    my_list = range(1000000)

    q = Queue()

    p1 = Process(target=do_sum, args=(q,my_list[:500000]))
    p2 = Process(target=do_sum, args=(q,my_list[500000:]))
    p1.start()
    p2.start()
    r1 = q.get()
    r2 = q.get()
    print r1+r2

if __name__=='__main__':
    main()

但是,使用多個進程執行此操作可能比在單個進程中執行此操作要慢,因為前后復制數據比立即匯總數據要昂貴。

歡迎並發編程的世界。

Python可以(也可以不)做的事情取決於兩件事。

  1. 操作系統可以(也可以不)做什么。 大多數操作系統將進程分配給核心。 要使用4個內核,您需要將問題分解為四個進程。 這比聽起來容易。 有時。

  2. 底層C庫可以(也可以不)做什么。 如果C庫暴露了操作系統的功能,並且操作系統公開了硬件的功能,那么您就是可靠的。

將問題分解為多個進程 - 特別是在GNU / Linux中 - 很容易。 將其分解為多步驟管道。

在匯總一百萬個數字的情況下,請考慮以下shell腳本。 假設一些假設的sum.py程序將stdin上的數字范圍或數字列表相加。

(sum.py 0 500000&sum.py 50000 1000000)| sum.py

這將有3個並發進程。 兩個正在做很多數字的總和,第三個是兩個數字相加。

由於GNU / Linux shell和操作系統已經為您處理了並發的某些部分,因此您可以設計簡單(非常非常簡單)的程序,這些程序從stdin讀取,寫入stdout,並且設計用於執行大型作業的一小部分。

您可以嘗試通過使用子進程來構建管道而不是將作業分配給shell來減少開銷。 但是,您可能會發現shell非常快速地構建管道。 (它直接用C語言編寫,並為您提供直接的OS API調用。)

當然,例如:

from multiprocessing import Process, Queue

thelist = range(1000*1000)

def f(q, sublist):
    q.put(sum(sublist))

def main():
    start = 0
    chunk = 500*1000
    queue = Queue()
    NP = 0
    subprocesses = []
    while start < len(thelist):
      p = Process(target=f, args=(queue, thelist[start:start+chunk]))
      NP += 1
      print 'delegated %s:%s to subprocess %s' % (start, start+chunk, NP)
      p.start()
      start += chunk
      subprocesses.append(p)
    total = 0
    for i in range(NP):
      total += queue.get()
    print "total is", total, '=', sum(thelist)
    while subprocesses:
      subprocesses.pop().join()

if __name__ == '__main__':
    main()

結果是:

$ python2.6 mup.py 
delegated 0:500000 to subprocess 1
delegated 500000:1000000 to subprocess 2
total is 499999500000 = 499999500000

請注意,這個粒度太精細,不值得產生進程 - 整體求和任務很小(這就是為什么我可以重新計算main中的總和作為一個檢查;-)並且來回移動太多數據(在事實上,子流程不需要獲得他們所使用的子列表的副本 - 索引就足夠了。 因此,它是一個“玩具示例”,其中多處理並不是真正的保證。 使用不同的體系結構(使用從隊列接收多個任務的子進程池,來回最小化數據移動等),然而在不太精細的任務上,您實際上可以獲得性能方面的好處。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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