python - 你如何在 python 中使用 numpy 数组进行 SIMD 处理?
问题描述
numpy
我有两个长度为 的大型二维正方形数组N
。
我有一个函数,它接收每个数组的行索引,对相应的行进行操作,然后将单个结果向量放在第三个数组中。
我的问题是我想并行化这个函数,但是,我不知道如何去做。我一直在看pool
Pythonmultiprocessing
库中的 -object,但我不清楚数据管理。
根据我目前的理解,pool.apply_async()
-method 接收一个可迭代对象,然后将其拆分以通过各个进程进行计算。给它提供一个元组列表是否合理,其中元组中的每个元素都是其中一个数组中的一行numpy
?
或者,有没有办法让每个进程一次将数组加载到内存中,然后在每次执行函数时继续使用这些加载的数组?在这种情况下,iterable 将再次是一个元组列表,但是每个元组将保存内存中数组的一对索引,而不是行本身。
最后,有什么方法可以让每个进程将结果向量提交到所有工作人员共享的单个数据对象中,然后我可以保存?
解决方案
您可以让每个进程保留自己的输入数组副本。但是它们不能写入共享输出数组;这就是使用子进程而不是线程的全部意义所在。(在线程中,全局解释器锁可能会阻止线程同时运行。)
在 Linux(可能还有 MacOS)中,已初始化的全局变量将由具有写时复制的子进程继承;只要子进程不尝试写入,变量就会使用共享内存。在 Windows 中,您必须为每个工作人员初始化此类全局变量。
这是如何做到这一点:
import numpy as np
from multiprocessing import Pool
PERSISTENT_DATA = {}
def func(ij):
i, j = ij
return PERSISTENT_DATA['a'][i] + PERSISTENT_DATA['b'][j]
def init_persistent_data(a, b):
PERSISTENT_DATA['a'] = a
PERSISTENT_DATA['b'] = b
def run_parallel():
n, m = 10, 5
np.random.seed(1)
a = np.random.randint(10, size=(n, m))
b = np.random.randint(10, size=(n, m))
# In Linux, these are inherited by the subprocesses.
init_persistent_data(a, b)
ij_tuples = [(0, 1), (1, 2)]
# In Linux, leave the initializer and initargs out.
with Pool(
processes=4,
initializer=init_persistent_data,
initargs=(a, b)
) as pl:
result = pl.map(func, ij_tuples)
result = np.array(result)
if __name__ == '__main__':
run_parallel()
推荐阅读
- mongodb - MongoDB 展平任意嵌套数组
- android - 如何根据下载国家/地区翻译您的应用程序
- python - 我尝试将使用烧瓶制作的网络应用程序添加到我的 WordPress 网站,但只有根路由有效。其他人返回404
- java - 我将如何着手将此代码转换为手动将参数提供给该方法并返回一个 2D char 数组?
- ios - 如何迁移到 Xcode 12.5
- azure-devops - ADO 组织目录问题
- forms - 使用 multipart/form-data 发送数据时实际文件数据在哪里
- youtube - Youtube 是否对所有用户可访问的链接使用 WebRisk API?
- image - Bootstrap 4 - 试图保持 flex 包装的图像溢出上一列
- r - 使用 geom_rect() 在混淆矩阵中绘制矩形