簡體   English   中英

多處理-限制CPU使用率

[英]Multiprocessing - limit CPU usage

我有一個代碼可以並行處理這個問題

 1| def function(name, params):
 2|   results = fits.open(name)
 3|    <do something more to results>
 4|    return results
 5|
 6| def function_wrapper(args):
 7|     return function(*args)
 8| 
 9| params = [...,...,..., etc]    
10|
11| p = multiprocessing..Pool(processes=(max([2, mproc.cpu_count() // 10])))
12| args_generator = ((name, params) for name in names)
13| 
14| dictionary = dict(zip(names, p.map(function_wrapper, args_generator)))

如果我正確理解了pool工作方式,則第11行中指定的進程數應該是給定時間產生的最大進程數。 因此,這應該限制我的CPU使用率,對嗎? 我的意思是,按照我的理解,如第11行所示,所使用的進程/ CPU的最大數量應為[2, number_of_cpus / 10]的最大值。

但是,當我運行代碼時,我看到啟動后不久所有CPU的使用率都是100%。 我想念什么嗎?

注意:對於上下文,由於要使用共享服務器,因此需要將CPU使用率限制為最大內核數。

更新 :添加我的代碼的修剪版本。 我沒有打開fits文件,而是創建了一個類似於我的頻譜的高斯曲線(盡管表現得更好...)。

對其進行修整有助於解決該問題。 在函數fnBootstrapInstance內部,擬合是在2-D數組(基本上是echelles光譜)上執行的,我使用for loop進行了迭代。 由於某種原因,刪除循環可以解決問題,並且僅使用了我指定的內核數。 我的猜測是,出於某種原因,for循環產生了一系列子進程(這就是它在htop )。 一次迭代一個數量級的Eehelles光譜解決了這個問題。

# Imports
#%matplotlib inline
import sys
import numpy as np
import matplotlib.pyplot as mplt
import numpy.random as rnd
import scipy.optimize as opt
import multiprocessing as mproc

# Functions ==================================================
def fnBootstrapInstance(XXX = None, YYY= None, function= None, lenght=None, fitBounds= None, initParams=None, **kwargs):

    # define samples
    indexes = sorted(rnd.choice(range(len(XXX)), size=lenght, replace=True))
    samplesXXX = XXX[indexes]
    samplesYYY = YYY[indexes]

    fitBounds = ([-np.inf,-np.inf,0,-np.inf],[np.inf,np.inf,np.inf,np.inf])

    params, cov = opt.curve_fit(function, samplesXXX.ravel(), samplesYYY.ravel(), p0=initParams,
                                bounds = fitBounds,
                                )

    return params

def wrapper_fnBootstrapInstance(args):
    return fnBootstrapInstance(**args)

def fnGaussian(dataXXX, Amp, mean, FWHM, B):
    return B - Amp * np.exp(-4 * np.log(2) * (((dataXXX - mean) / FWHM) ** 2))
# Functions ==================================================


# Noise Parameters
arrLen = 1000
noiseAmp = 0.
noiseSTD = .25

# Gaussian Data Parameters
amp = 1.
mean = 10
FWHM = 30.
B = 1.

# generate random gauss data
arrGaussXXX = np.linspace(-50, 60,num = arrLen)
arrGaussNoise = rnd.normal(noiseAmp,noiseSTD, arrLen)
arrGaussYYY = fnGaussian(arrGaussXXX, amp, mean, FWHM, B) + arrGaussNoise

# multiprocessing bit
numIterations = 1000

mprocPool = mproc.Pool(processes=(max([2, mproc.cpu_count() // 10])))

initParams = [max(arrGaussYYY) - min(arrGaussYYY), np.median(arrGaussXXX),
                        max(arrGaussXXX) - min(arrGaussXXX), max(arrGaussYYY)]

args_generator = [{'XXX':arrGaussXXX, 'YYY':arrGaussYYY, 'function':fnGaussian, 'initParams':initParams,
                    'lenght':200} for n in range(numIterations)]

fitParams = []
for results in  mprocPool.imap(wrapper_fnBootstrapInstance, args_generator):
    fitParams.append([results[0],results[1],results[2],results[3]])



bootParams = [(np.nanmedian(param),np.nanstd(param)) for param in np.array(fitParams).T]
print '\n'.join('{:.2f}+-{:.2f} ({:.1f}%)'.format(param[0],param[1], param[1]/param[0]*100) for param in bootParams)

mplt.figure(figsize=(20,10))
mplt.plot(arrGaussXXX, arrGaussYYY,'+')  
for params in fitParams: 
    mplt.plot(arrGaussXXX,fnGaussian(arrGaussXXX,*params),'r', alpha = .5) 
mplt.show()


mprocPool.close()

謝謝大家!

考慮使用multiprocessing.pool.ThreadPool 它提供與multiprocessing.Pool相同的API,但將工作負載抽象為Threads集合。 請注意,如果您的CPU支持超線程,那么它很可能會在物理內核上分配工作負載。

暫無
暫無

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

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