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