我有一个应用程序,它使用了许多继承自HasTraits
的类。其中一些类管理对数据的访问,而另一些类提供分析该数据的功能。这非常适用于gui - 我可以检查数据和分析代码是否正在做它应该做的事情。但是,我注意到当我使用这些类进行gui-less计算时,系统上的所有cpu都会被使用。
这是一个显示cpu用法的小例子:
from traits.api import HasTraits, List, Int, Enum, Instance
import numpy as np
import psutil
from itertools import combinations
"""
Small example of high CPU usage by traited classes
"""
class DataStorage(HasTraits):
nsamples = Int(2000)
samples = List
def _samples_default(self):
return np.random.randn(self.nsamples,2000).tolist()
def sample_samples(self,indices):
""" return a 2D array of data at indices """
return np.array(
[self.samples[i] for i in indices])
class DataAccessor(HasTraits):
""" Class that grabs data and computes something """
measure = Enum("correlation","covariance")
data_source = Instance(DataStorage,())
def compute_measure(self,indices):
""" example of some computation """
samples = self.data_source.sample_samples(indices)
percentage = psutil.cpu_percent(interval=0, percpu=True)
if self.measure == "correlation":
result = np.corrcoef(samples)
elif self.measure == "covariance":
result = np.cov(samples)
return percentage
# Run a simulation to see cpu usage
analyzer = DataAccessor()
usage = []
n_iterations = 0
max_iterations = 500
for combo in combinations(np.arange(2000),500):
# evaluate the measurement on a subset of the data
usage.append(analyzer.compute_measure(combo))
n_iterations += 1
if n_iterations > max_iterations:
break
print n_iterations
use_percents = np.array(usage).T
当我在运行CentOS的8-cpu机器上运行时,top
报告python进程大约600%。
>>> use_percents.mean(1)
显示
array([ 67.05548902, 67.06906188, 66.89041916, 67.28942116,
66.69421158, 67.61437126, 99.8007984 , 67.31996008])
我的计算是令人尴尬的并行,所以将其他cpu用于拆分工作会很棒。有谁知道这里发生了什么?一个普通的python版本在单个cpu上使用100%。
有没有办法将所有内容保存到单个cpu而不重写所有没有特征的类?
答案 0 :(得分:0)
Traits不会导致CPU使用率。没有Traits就可以很容易地重写这段代码,你会发现你得到了相同的CPU使用模式(至少,我这样做)。
相反,您可能会看到的是您的numpy构建链接的BLAS库的CPU使用率。 numpy.corrcoeff()
调用numpy.cov()
,numpy.cov()
的大部分计算都由numpy.dot()
调用占用,后者使用BLAS执行矩阵 - 矩阵乘法。如果它是一个优化的BLAS库,那么它通常会在内部使用非Python线程来在您的CPU之间拆分这些计算。您将不得不查阅优化的BLAS库的文档,以了解如何更改它。