当前位置: 首页 > 面试题库 >

导入scipy破坏了Python中的多处理支持

龙飞
2023-03-14
问题内容

我遇到了一个我无法解释的奇怪问题。我希望有人可以帮助您!

我正在运行Python 2.7.3和Scipy
v0.14.0,并试图实现一些非常简单的多处理器算法,以使用该模块加速我的代码multiprocessing。我设法使一个基本的示例工作:

import multiprocessing
import numpy as np
import time
# import scipy.special


def compute_something(t):
    a = 0.
    for i in range(100000):
        a = np.sqrt(t)
    return a

if __name__ == '__main__':

    pool_size = multiprocessing.cpu_count()
    print "Pool size:", pool_size
    pool = multiprocessing.Pool(processes=pool_size)

    inputs = range(10)

    tic = time.time()
    builtin_outputs = map(compute_something, inputs)
    print 'Built-in:', time.time() - tic

    tic = time.time()
    pool_outputs = pool.map(compute_something, inputs)
    print 'Pool    :', time.time() - tic

运行正常,返回

Pool size: 8
Built-in: 1.56904006004
Pool    : 0.447728157043

但是,如果我取消注释该行import scipy.special,则会得到:

Pool size: 8
Built-in: 1.58968091011
Pool    : 1.59387993813

而且我可以看到只有一个核心在我的系统上进行工作。实际上,从scipy包导入任何模块似乎都具有这种效果(我已经尝试了几次)。

有任何想法吗?我以前从未见过这样的情况,在这种情况下,似乎无害的导入会产生如此奇怪和意外的影响。

谢谢!

更新(1)

将scipy导入行移至该函数可以compute_something部分改善此问题:

Pool size: 8
Built-in: 1.66807389259
Pool    : 0.596321105957

更新(2)

感谢@larsmans在不同的系统上进行测试。使用Scipy v.0.12.0尚未确认问题。将此查询移至scipy邮件列表,并将发布所有答案。


问题答案:

在深入研究并将问题发布在Scipy
GitHub网站上之后,我找到了解决方案。

在我开始之前,这是记录非常好这里-我只是给出一个概述。

这个问题
涉及到SciPy的版本,或numpy的,我用。它起源于Numpy和Scipy用于各种线性代数例程的系统BLAS库。您可以通过运行来确定Numpy链接到哪些库

python -c 'import numpy; numpy.show_config()'

如果在Linux中使用OpenBLAS,则可能会发现CPU关联性设置为1,这意味着一旦这些算法以Python(通过Numpy /
Scipy)导入了Python,则最多可以访问CPU的一个核心。要测试这一点,请在Python终端中运行

import os
os.system('taskset -p %s' %os.getpid())

如果CPU亲和力返回fff,您可以访问多个内核。就我而言,它是这样开始的,但是在导入numpy或scipy.any_module时,它将切换到1,因此是我的问题。

我找到了两种解决方案:

更改CPU关联

您可以在main函数的顶部手动设置主进程的CPU亲和力,以使代码如下所示:

import multiprocessing
import numpy as np
import math
import time
import os

def compute_something(t):
    a = 0.
    for i in range(10000000):
        a = math.sqrt(t)
    return a

if __name__ == '__main__':

    pool_size = multiprocessing.cpu_count()
    os.system('taskset -cp 0-%d %s' % (pool_size, os.getpid()))

    print "Pool size:", pool_size
    pool = multiprocessing.Pool(processes=pool_size)

    inputs = range(10)

    tic = time.time()
    builtin_outputs = map(compute_something, inputs)
    print 'Built-in:', time.time() - tic

    tic = time.time()
    pool_outputs = pool.map(compute_something, inputs)
    print 'Pool    :', time.time() - tic

请注意,选择一个高于内核数的值taskset似乎无关紧要-它仅使用最大可能数。

切换BLAS库

解决方案记录在上面链接的站点上。基本上:安装libatlas,然后update-alternatives将numpy指向ATLAS,而不是OpenBLAS。



 类似资料:
  • 我有一个非常简单的SOAP客户机,它是我在wsimport实用程序的帮助下针对自己的web服务创建的。客户端工作得非常好,但是当我添加一个处理程序时就崩溃了。下面是我的工作客户端,它将“1”打印到控制台... 现在,有趣的部分来了,这是同一个客户机,处理程序实现后面跟着输出... 输出 请注意,在输出中,在异常之前打印了3行,这些来自我的处理程序类,这证明它已注册并正常工作。我意识到这是一些有限的

  • 我使用悬停库创建一个动画时,用户悬停在一个

  • 问题内容: 我在页面上添加了一个简单的文件,该文件在和原型中添加了一些非常普通的常见任务功能。 经过反复试验,我发现向,添加任何函数,无论其名称或功能如何都会导致jQuery中的Javascript错误: 罪魁祸首? 我在attr:function {}声明中得到的第1056行的错误: 显然G.replace是未定义的。 很明显,有些事情我只是没有用原型制作而已,但我很痛苦地未能弄清楚它是什么。

  • 我正在从一个空的MVC构建一个OWIN登录,我刚刚开始添加这个部分,在创建一个要放入URL的身份声明之后,使用我的数据库登录用户。 这是我创建登录用户声明的代码 这是我的Show.cshtml代码 这是我的代码,我调用我的数据库,并为登录用户存储我的数据 我的登录(登录模型输入)完成并返回到Show.cshtml,然后在这里有一个异常@Html。AntiForgeryToken().我得到的例外是

  • 问题内容: 我知道有几个类似的问题,但是我很难理解我在获取和浏览文档时遇到的错误,而类似的问题还没有帮助。如果有的话,类似的问题会让我觉得自己在做的事是对的。 我有以下文件: src / main.py src / pack / pack.py src / pack / util.py src / pack / _ init _.py * EMPTY FILE 当我从目录运行时,它可以工作(打印“

  • 演示 该网站最初有一些有限的文本,和大量复杂的图形,并在所有5个浏览器上呈现良好。我添加了更多的文本,但现在在Safari中无法使用。我认为转换可能更糟--试着缩放jsfiddle,您会看到人工制品的出现和消失取决于缩放。 有什么想法吗?Safari是不是刚刚坏了?