1

我有一个应用程序,它使用了许多继承自HasTraits. 其中一些类管理对数据的访问,而其他类则提供分析该数据的功能。这对于 gui 来说非常有用——我可以检查数据和分析代码是否在做它应该做的事情。但是,我注意到,当我将这些类用于无 gui 计算时,系统上的所有 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 本地?

4

1 回答 1

0

特征不会导致 CPU 使用率。在没有 Traits 的情况下重写这段代码很容易,你会看到你得到了相同的 CPU 使用模式(至少,我这样做)。

相反,您可能看到的是您的 numpy 构建所链接的 BLAS 库的 CPU 使用率。numpy.corrcoeff()调用numpy.cov(),并且 的大部分计算numpy.cov()由调用占用,numpy.dot()调用使用 BLAS 进行矩阵-矩阵乘法。如果它是一个优化的 BLAS 库,那么它通常会在内部使用非 Python 线程在 CPU 之间拆分这些计算。您必须查阅优化的 BLAS 库的文档以了解如何更改它。

于 2013-06-07T21:20:58.980 回答