- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试在 Python 中使用多处理池。这是我的代码:
def f(x):
return x
def foo():
p = multiprocessing.Pool()
mapper = p.imap_unordered
for x in xrange(1, 11):
res = list(mapper(f,bar(x)))
当 xrange
很小如 xrange(1, 6)
时,此代码使用所有 CPU(我有 8 个 CPU)。但是,当我将范围增加到 xrange(1, 10)
时。我观察到只有 1 个 CPU 以 100% 的速度运行,而其余的只是闲置。可能是什么原因?是否因为当我增加范围时,操作系统会因过热而关闭 CPU?
我该如何解决这个问题?
为了重现我的问题,我创建了这个示例:它是从字符串问题生成的简单 ngram。
#!/usr/bin/python
import time
import itertools
import threading
import multiprocessing
import random
def f(x):
return x
def ngrams(input_tmp, n):
input = input_tmp.split()
if n > len(input):
n = len(input)
output = []
for i in range(len(input)-n+1):
output.append(input[i:i+n])
return output
def foo():
p = multiprocessing.Pool()
mapper = p.imap_unordered
num = 100000000 #100
rand_list = random.sample(xrange(100000000), num)
rand_str = ' '.join(str(i) for i in rand_list)
for n in xrange(1, 100):
res = list(mapper(f, ngrams(rand_str, n)))
if __name__ == '__main__':
start = time.time()
foo()
print 'Total time taken: '+str(time.time() - start)
当 num
较小时(例如,num = 10000
),我发现所有 8 个 CPU 都被使用。但是,当 num
非常大时(例如,num = 100000000
)。仅使用 2 个 CPU,其余空闲。这是我的问题。
注意:当num
太大时可能会导致系统/VM 崩溃。
最佳答案
首先,ngrams
本身会花费很多时间。虽然这种情况正在发生,但它显然只是一个核心。但即使完成了(这很容易测试,只需将 ngrams
调用移到 mapper
之外,并在前后抛出一个 print
它),您仍然只使用一个核心。我得到 1 个核心 100%,其他核心都在 2% 左右。
如果您在 Python 3.4 中尝试同样的事情,情况会有所不同——我仍然得到 1 个核心的 100%,但其他核心是 15-25%。
那么,这是怎么回事?那么,在 multiprocessing
中,传递参数和返回值总是有一些开销。在您的情况下,这种开销完全淹没了实际工作,即 return x
。
开销的工作原理如下:主进程必须对值进行 pickle,然后将它们放入队列,然后等待另一个队列中的值并取消 pickle。每个子进程在第一个队列上等待,unpickles 值,做你的无所事事的工作,pickle 值,并将它们放在另一个队列中。必须同步对队列的访问(通过大多数非 Windows 平台上的 POSIX 信号量,我认为是 Windows 上的 NT 内核互斥量)。
据我所知,您的进程 99% 以上的时间都在等待队列或读取或写入队列。
这不是太出乎意料,因为您有大量数据要处理,而且除了 pickling 和 unpickling 数据之外根本没有计算。
如果您在 CPython 2.7 中查看 SimpleQueue
的源代码,pickling 和 unpickling 发生在持有锁的情况下。因此,几乎任何后台进程所做的所有工作都是在持有锁的情况下发生的,这意味着它们最终都在单个内核上序列化。
但是在CPython 3.4 ,pickling 和 unpickling 发生在锁的外面。显然,这足以使用 15-25% 的内核。 (我相信这个变化发生在 3.2 中,但我懒得去追踪它。)
尽管如此,即使在 3.4 上,您花在等待访问队列上的时间也比做任何事情都多得多,甚至是 multiprocessing
开销。这就是核心最多只能达到 25% 的原因。
当然,你花在开销上的时间比实际工作多几个数量级,这使得这不是一个很好的测试,除非你试图测试你可以从特定的中获得的最大吞吐量>multiprocessing
在您的机器或其他设备上实现。
一些观察:
chunksize=1000
或类似的在这里没有帮助),那可能会解决大部分问题你的问题。multiprocessing
或 PyPI 的第三方 multiprocessing
库之一(或升级到 Python 3.x ), 只是为了将酸洗移出锁。关于python - Python 中的多处理池 - 仅使用单个 CPU,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30094793/
最近,我们将专用 SQL 池部署到生产中的 Synapse 工作区。在开发中,我们可以访问无服务器 SQL 池和专用 SQL 池。但是,在生产中,我们可以访问无服务器 SQL 池,但无法访问专用 SQ
假设您从一个项目公开 WCF 服务,并使用“添加服务引用”(在本例中为 Framework 3.5 WPF 应用程序)在另一个项目中使用它。 当您重新实例化 ClientBase 派生代理时,Clie
我有一个函数,它使用 multiprocessing.Pool 并行处理一个数据集中的所有数据。 from multiprocessing import Pool ... def func():
我正在尝试使用进程对象在 python 中使用工作池。每个 worker (一个进程)进行一些初始化(花费大量时间),传递一系列作业(理想情况下使用 map()),并返回一些东西。除此之外,不需要任何
我是软件工程师,最近我构建了我的 Linux 机器,想探索更多系统管理员类型的任务。我已经探索并阅读了很多关于 ZFS 的内容,但我越来越困惑,因为每篇文章对它的描述都不一样。 Everything
我有 zfs 池: $ sudo zpool status lxd pool: lxd state: ONLINE scan: none requested config: NAME
我有一个基于 Actor 的项目,对于其中的一部分,我必须使用一些接收消息的 Actor ,然后一个 Actor 分别分配给每个请求,每个 Actor 负责执行其消息请求,所以我需要类似线程的东西我的
我已经使用 QEMU 模拟器成功地将 FreeBSD 安装到原始图像文件中。我已经使用 ZFS 文件系统 (ZFS POOL) 格式化了图像文件。 使用下面的命令我已经成功地挂载了准备好由 zpool
我正在使用 multiprocessor.Pool并行处理一些文件。该代码等待接收文件,然后使用 Pool.apply_async 将该文件发送给工作人员。 ,然后处理文件。 这段代码应该一直在运行,
我正在使用带有光滑的 Bonecp 数据源。并发现池包含关闭的连接所以我总是遇到这个异常 java.sql.SQLException: Connection is closed! at com
我有apartment gem的 Multi-Tenancy Rails应用程序,我可以使用apartment-sidekiq在每个工作程序中成功切换数据库租户。但是,sidekiq worker 正
ZFS 池可能由数据集(文件系统、快照等)或卷组成。 ZFS 卷就像 block 设备,但我不明白池和文件系统之间的区别。当我通过 zpool create pool1 sda sdb sdc 创建
我在 docker 容器上运行了 airflow。我正在使用 airflow 2.0.2 版。 我知道我实际上可以通过 UI 创建池。但我正在寻找一种通过 pools.json 文件在 docker
我在tomcat中有一个jdbc池,用于建立数据库连接。我在使用后没有显式关闭连接对象。我的“maxActive”参数设置为100。应用程序运行了一段时间,但随后失败进行数据库查询。它会等待无限时间来
阅读 PostgreSQL 文档 here我读了以下内容: As well, connections requested for users other than the default config
我在 docker 容器上运行了 airflow。我正在使用 airflow 2.0.2 版。 我知道我实际上可以通过 UI 创建池。但我正在寻找一种通过 pools.json 文件在 docker
我正在读取一个大的 URL 文件并向服务发出请求。该请求由返回 ListenableFuture 的客户端执行。现在我想保留一个 ListenableFuture 池,例如最多同时执行 N 个 Fut
我想使用队列来保存结果,因为我希望消费者(串行而不是并行)在工作人员产生结果时处理工作人员的结果。 现在,我想知道为什么以下程序挂起。 import multiprocessing as mp imp
我正在开发一个单页应用程序,目前正在构建一个 JQuery、ajax 函数,以便我的所有调用都能通过。 对于一个典型的页面,我可能有 3 个 ajax 调用。我的想法是,如果用户互联网出去将这些 aj
我有一个单位类及其一些子类(弓箭手、剑客等)。我怎样才能创建一个回收所有单元类型子类的池? 最佳答案 这是不可能的,因为池只能包含一种特定类型的对象。否则你可能会遇到这样的情况: Pool unitP
我是一名优秀的程序员,十分优秀!