如何在python中使用numpy数组进行SIMD处理?

2024-04-29 19:25:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我有两个长度为N的大型2D方形numpy数组

我有一个函数,它接收每个数组的行索引,对相应的行进行操作,然后在第三个数组中放置一个结果向量

我的问题是,我想并行化这个函数,但是,我不知道如何去做它。我一直在查看Python的multiprocessing库中的pool-对象,但我不清楚数据管理

根据我目前的理解,pool.apply_async()-方法接收一个iterable,然后将其拆分,以便通过单个进程进行计算。向它提供一个元组列表是否合理,其中元组中的每个元素都是numpy数组中的一行

或者,是否有一种方法可以让每个进程一次将数组加载到内存中,然后在每次执行函数时继续使用这些加载的数组?在这种情况下,iterable将再次是一个元组列表,但是每个元组将为内存中的数组保存一对索引,而不是行本身

最后,是否有任何方法可以让每个进程将结果向量提交到所有工作人员共享的单个数据对象中,然后保存


Tags: 对象方法函数内存numpy列表进程数组
1条回答
网友
1楼 · 发布于 2024-04-29 19:25:23

您可以让每个进程保留自己的输入数组副本。但它们不能写入共享输出数组;这就是使用子进程而不是线程的全部意义。(在线程中,全局解释器锁可能会阻止线程同时运行。)

在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()

相关问题 更多 >