2013-04-05 76 views
3

我有一個python腳本,必須採取大數據集的許多排列,對每個排列進行評分,並且只保留最高得分排列。該數據集非常大,以至於該腳本需要將近3天才能運行。如何在python腳本中訪問所有計算核心進行計算?

當我在Windows中檢查我的系統資源時,我的CPU中只有12%正在使用,並且8個內核中只有4個工作。即使我把python.exe進程置於最高優先級,這也不會改變。

我的假設是專用更多的CPU使用率來運行腳本可以使其運行速度更快,但我的最終目標是減少至少一半的運行時間。有沒有一個Python模塊或一些代碼可以幫助我做到這一點?另外,這聽起來像是一個可以從更智能的算法中受益的問題嗎?

預先感謝您!

回答

3

有幾種方法可以解決這個問題,但請查看multiprocessing模塊。這是創建多個進程的標準庫模塊,類似於線程,但沒有GIL的限制。

您還可以查看優秀的Celery庫。這是一個分佈式任務隊列,並且有很多很棒的功能。它的安裝非常簡單,並且易於使用。

-1

由於全局解釋器鎖定,一個Python進程無法利用多個內核。但是,如果你能以某種方式並行處理你的問題(你應該這樣做),那麼你可以使用multiprocessing來產生儘可能多的Python進程,因爲你擁有核心並在每個子進程中處理這些數據。

0

你應該產生新的進程而不是線程來利用CPU中的核心。我的一般規則是每個核心一個進程。因此,您可以將問題輸入空間分成可用的核心數量,每個進程都會成爲問題空間的一部分。

Multiprocessing是最好的。您也可以使用Parallel Python

1

我可以用一個簡單的代碼示例來回答一個HOWTO。在運行時,運行/ bin/top並查看您的進程。很簡單。請注意,我甚至包括如何從鍵盤中斷清除 - 沒有這些,你的子進程將繼續運行,你將不得不手動殺死它們。

from multiprocessing import Process 
import traceback 
import logging 
import time 

class AllDoneException(Exception): 
    pass 

class Dum(object): 
    def __init__(self): 
     self.numProcesses = 10  
     self.logger = logging.getLogger() 
     self.logger.setLevel(logging.INFO) 
     self.logger.addHandler(logging.StreamHandler()) 

    def myRoutineHere(self, processNumber): 
     print "I'm in process number %d" % (processNumber) 
     time.sleep(10) 
     # optional: raise AllDoneException 

    def myRoutine(self): 
     plist = [] 
     try: 
      for pnum in range(0, self.numProcesses): 
       p = Process(target=self.myRoutineHere, args=(pnum,)) 
       p.start() 
       plist.append(p) 
      while 1: 
       isAliveList = [p.is_alive() for p in plist] 
       if not True in isAliveList: 
        break 
       time.sleep(1) 
     except KeyboardInterrupt: 
      self.logger.warning("Caught keyboard interrupt, exiting.") 
     except AllDoneException: 
      self.logger.warning("Caught AllDoneException, Exiting normally.") 
     except: 
      self.logger.warning("Caught Exception, exiting: %s" % (traceback.format_exc())) 
     for p in plist: 
      p.terminate() 

d = Dum() 
d.myRoutine()