python - 如何有效地使用多处理来加速大量微小的任务?
问题描述
我在 Python 中遇到了一些麻烦multiprocessing.Pool
。我有两个numpy
数组列表a
和b
,其中
a.shape=(10000,3)
和
b.shape=(1000000000,3)
然后我有一个函数可以做一些计算,比如
def role(array, point):
sub = array-point
return (1/(np.sqrt(np.min(np.sum(sub*sub, axis=-1)))+0.001)**2)
接下来,我需要计算
[role(a, point) for point in b]
为了加快速度,我尝试使用
cpu_num = 4
m = multiprocessing.Pool(cpu_num)
cost_list = m.starmap(role, [(a, point) for point in b])
m.close
整个过程大约需要70s,但如果我设置cpu_num = 1
,处理时间减少到60s...我的笔记本电脑有6核,供参考。
这里我有两个问题:
- 我做错了
multiprocessing.Pool
什么吗?如果我设置,为什么处理时间会增加cpu_num = 4
? - 对于这样的任务(每个 for 循环都是一个非常小的过程),我应该使用多处理来加速吗?我觉得每次python填充
Pool
都比处理函数花费的时间长role
...
任何建议都非常受欢迎。
解决方案
如果任务太小,那么多处理开销将成为您的瓶颈,您将一无所获。
如果您必须传递给工作人员或工作人员必须返回的每个任务的数据量,那么您也不会赢得很多(甚至什么都没有)
如果您有 10.000 个小任务,那么我建议您创建一个元任务列表。每个元任务将包括执行例如 20 个小任务。
meta_tasks = []
for idx in range(0, len(tiny_tasks), 20):
meta_tasks.append(tiny_tasks[idx:idx+20])
然后将元任务传递到您的工作池。
推荐阅读
- qt - Qt qml MediaPlayer/Video 仅再现声音(无视频)
- html - 使用 CSS 维护 ID attr 更改
- java - 使用 (:date INTERVAL :field HOUR) 创建 JPQL 语句
- jhipster - 从具有密码授予类型的移动应用程序请求的正确方法是什么?
- php - PHP在不满足条件的情况下输入if-condition
- javascript - 使用 D3.js 的 3D 条形图的透视问题
- wix - 我们可以将 KeyPath="no" 与“组件”元素与注册表一起使用吗
- .net - Windows 工作流:如何在发送活动中为 OperationName 参数指定命名空间 URI?
- c++ - iMAC 上的 Qt5.11.2、QSqlDatabase 和 MariaDB
- vba - 将 CSV 值导入变量 VBA (MSAccess)