首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >numpy“锁定”跨进程的资源是什么?

numpy“锁定”跨进程的资源是什么?
EN

Stack Overflow用户
提问于 2018-09-19 13:05:23
回答 1查看 274关注 0票数 2

因此,一个朋友注意到了一些关于numpy的好奇之处。下面是一个最小的示例,它首先以串行方式运行相同的脚本,而不是在各自的进程中并行两个实例:

代码语言:javascript
运行
复制
#!/bin/bash
# This is runner.sh

fl=/tmp/$(mktemp test_XXXXX.py)
trap "rm -fv '$fl'" EXIT
cat - > "$fl" <<-'EndOfHereDoc'
#!/usr/bin/env python
import numpy as np
import sys

if __name__ == '__main__':
    if len(sys.argv)>1: print(sys.argv[1] +' start: '+ str(datetime.datetime.now()))
    cube_size=100
    cube=np.zeros((cube_size,cube_size,cube_size))
    cube_ones=np.ones((cube_size,cube_size,cube_size))

    for x in range(10000):
        np.add(cube_ones,cube,out=cube)
    if len(sys.argv)>1: print(sys.argv[1] +' start: '+ str(datetime.datetime.now()))
EndOfHereDoc

echo "Serial"
time python "$fl" 0
echo

echo "Parallel"
time python "$fl" 1&
time python3 "$fl" 2&
wait

rm -fv "$fl"
trap '' EXIT

其产出如下:

代码语言:javascript
运行
复制
$ runner.sh 
Serial
0 start: 2018-09-19 15:46:52.540881
0 end: 2018-09-19 15:47:04.592280

real    0m12,105s
user    0m12,084s
sys 0m0,020s

Parallel
1 start: 2018-09-19 15:47:04.665260
2 start: 2018-09-19 15:47:04.780635
2 end: 2018-09-19 15:47:27.053261

real    0m22,480s
user    0m22,448s
sys 0m0,128s
1 end: 2018-09-19 15:47:27.097312

real    0m22,505s
user    0m22,409s
sys 0m0,040s
removed '/tmp/test_zWN0V.py'

没有加速。就好像进程一个接一个地运行。我假设numpy只使用一个资源,而另一个进程则等待释放该资源。,但是这里到底发生了什么呢? GIL只应该是多线程问题,而不是多进程问题,对吗?我觉得特别奇怪的是,p2并不是简单地等待p1完成。相反,这两个进程都需要22s才能完成。我希望一个人能得到资源,并在一半的时间内完成。而另一个等待直到第一个释放它,并采取额外的~12。

请注意,在使用python自己的multiprocessing模块在Pool中运行python代码时,也会注意到这一点。但是,如果您所做的事情不涉及某些特定的numpy函数,则不会发生这种情况,例如:

代码语言:javascript
运行
复制
cube_size=25
cube=[0 for i in range(cube_size**3)]

for x in range(10000):
    cube = [ value + 1 for value in cube]

编辑:

我有一个真正的四核CPU。我一直在想超线程,这不是问题所在。在单进程部分,一个CPU 100%,其余空闲。在这两个过程部分中,两个是100%,其余是空闲的(按照htop)。我知道numpy在后台运行ATLAS、LAPACK和BLAS库,它们不是Python (实际上是纯C或Fortran)。这些可能利用并行技术。我的问题是,为什么CPU利用率没有出现这种情况呢?

EN

回答 1

Stack Overflow用户

发布于 2018-09-19 14:37:14

Numpy不像核心Python那样受到GIL的限制。这是因为numpy只将数组存储为Python对象。实际数据本身存储为C中定义的“原始”类型,这也是为什么对numpy数组的迭代要比遍历Python列表慢得多的原因。numpy数组必须为它生成的每个值构建一个Python对象,而Python列表中已经有Python对象。

由于numpy不受GIL的阻碍,所以它能够在可用的地方使用线程化的数学库。也就是说,您的并行进程运行时间更长,因为每个进程已经使机器变得最大,因此两个进程都在争夺相同的资源。

看看输出,看看您的机器上有什么可用的(请注意,它非常冗长)。

代码语言:javascript
运行
复制
import numpy.distutils.system_info as sysinfo
sysinfo.show_all()
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52406563

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档