簡體   English   中英

Python多處理:限制使用的核心數

[英]Python multiprocessing: restrict number of cores used

我想知道如何將N個獨立任務分配給具有L個核心的機器上的M個處理器,其中L> M. 我不想使用所有處理器,因為我仍然希望I / O可用。 我試過的解決方案似乎被分發到所有處理器,使系統陷入困境。

我假設多處理模塊是可行的方法。

我做數值模擬。 我的背景是物理學,而不是計算機科學,所以不幸的是,我經常不完全理解涉及標准任務模型的討論,如服務器/客戶端,生產者/消費者等。

以下是我嘗試過的一些簡化模型:

假設我有一個運行模擬的函數run_sim(**kwargs) (參見下面的內容),以及用於模擬的一長串kwargs,我有一個8核心機器。

from multiprocessing import Pool, Process

#using pool
p = Pool(4)
p.map(run_sim, kwargs)

# using process
number_of_live_jobs=0
all_jobs=[]
sim_index=0
while sim_index < len(kwargs)+1:
   number_of_live_jobs = len([1 for job in all_jobs if job.is_alive()])
   if number_of_live_jobs <= 4:
      p = Process(target=run_sim, args=[], kwargs=kwargs[sim_index])
      print "starting job", kwargs[sim_index]["data_file_name"]
      print "number of live jobs: ", number_of_live_jobs
      p.start()
      p.join()
      all_jobs.append(p)
      sim_index += 1

當我用“頂部”然后“1”查看處理器使用情況時,無論如何,所有處理器似乎都被使用了。 我錯誤地解釋了“top”的輸出並不是不可能的,但是如果run_simulation()是處理器密集型的,那么機器會嚴重run_simulation()

假設模擬和數據:

# simulation kwargs
numbers_of_steps = range(0,10000000, 1000000)
sigmas = [x for x in range(11)]
kwargs = []
for number_of_steps in numbers_of_steps:
   for sigma in sigmas:
      kwargs.append(
         dict(
            number_of_steps=number_of_steps,
            sigma=sigma,
            # why do I need to cast to int?
            data_file_name="walk_steps=%i_sigma=%i" % (number_of_steps, sigma),
            )
         )

import random, time
random.seed(time.time())

# simulation of random walk
def run_sim(kwargs):
   number_of_steps = kwargs["number_of_steps"]
   sigma = kwargs["sigma"]
   data_file_name = kwargs["data_file_name"]
   data_file = open(data_file_name+".dat", "w")
   current_position = 0
   print "running simulation", data_file_name
   for n in range(int(number_of_steps)+1):
      data_file.write("step number %i   position=%f\n" % (n, current_position))
      random_step = random.gauss(0,sigma)
      current_position += random_step

   data_file.close()

您可能需要查看以下包:

http://pypi.python.org/pypi/affinity

它是一個使用sched_setaffinity和sched _getaffinity的包。

缺點是它是高度特定於Linux的。

如果您使用的是Linux,請在啟動程序時使用taskset

通過fork(2)創建的子級繼承其父級的CPU關聯掩碼。 關聯掩碼保留在execve(2)上。

使用taskset(1)
Linux用戶手冊
使用taskset(1)

NAME任務集 - 檢索或設置進程的CPU關聯

大綱taskset [options] mask命令[arg] ... taskset [options] -p [mask] pid

說明taskset用於在給定PID的情況下設置或檢索正在運行的進程的CPU關聯,或者以給定的CPU關聯性啟動新的COMMAND。 CPU affinity是一種調度程序屬性,它將進程“綁定”到系統上的給定CPU集。 Linux調度程序將遵循給定的CPU關聯,並且該進程不會在任何其他CPU上運行。 請注意,Linux調度程序還支持自然CPU親和性:由於性能原因,調度程序會嘗試將進程保留在同一CPU上。 因此,強制特定的CPU關聯僅在某些應用程序中有用。

CPU親和性表示為位掩碼,最低位對應於第一個邏輯CPU,最高位對應於最后一個邏輯CPU。 並非所有CPU都可能存在於給定系統上,但掩碼可能指定的CPU數量多於現有CPU數量。 檢索到的掩碼將僅反映與系統上物理上的CPU相對應的位。 如果給出了無效掩碼(即,對應於當前系統上沒有有效CPU的掩碼),則返回錯誤。 掩碼通常以十六進制給出。

在我的雙核機器上,進程總數很高,即如果我這樣做

p = Pool(1)

然后我只看到在任何給定時間使用的一個CPU。 該過程可以自由遷移到不同的處理器 ,但隨后另一個處理器處於空閑狀態。 我沒有看到您的所有處理器同時使用的情況,因此我不了解這與您的I / O問題有何關聯。 當然,如果您的模擬受I / O限制,那么無論核心使用情況如何,您都會看到緩慢的I / O ...

可能是一個愚蠢的觀察,請原諒我對Python的經驗不足。

但是你完成的任務的while循環輪詢不會睡覺並且一直消耗一個核心,不是嗎?

另一件需要注意的事情是,如果你的任務是I / O綁定的,你應該調整你的並行磁盤數(?)...如果它們是在不同的機器上安裝NFS你可能有M> L 。

g'luck!

您可以嘗試使用pypar模塊。 我不確定如何使用affinity來使用affinity設置cpu親和力到某個核心

暫無
暫無

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

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