gpt4 book ai didi

python - ipython并行和非复制发送numpy数组

转载 作者:太空宇宙 更新时间:2023-11-03 17:54:56 25 4
gpt4 key购买 nike

我试图了解 IPython 并行的 numpy 数组的非复制发送/接收会发生什么。我知道消息的非复制接收是只读的,但这使我期望收到的 numpy 数组就像一个 View ,指向原始数组(至少在共享内存机器上)。然后我期望如果 numpy 数组被修改计算节点之一,我在笔记本中对该数组的 View 将被更新,然而,情况似乎并非如此。为了演示什么让我感到困惑,代码

from IPython.parallel import Client
dv = Client()[:]

with dv.sync_imports():
import numpy

dv.execute('a = numpy.zeros(2)')
print dv['a']
mya = dv['a'][1] # my copy of the array in the notebook
# mya[0] = -1 # can't assign to mya because it is read-only
dv.execute('a[1] = 1') # update the arrays on the compute nodes
print mya # value of mya is not updated
print dv['a'] # even though the arrays are updated on the compute nodes

有输出

importing numpy on engine(s)
[array([ 0., 0.]), array([ 0., 0.]), array([ 0., 0.]), array([ 0., 0.])]
[ 0. 0.]
[array([ 0., 1.]), array([ 0., 1.]), array([ 0., 1.]), array([ 0., 1.])]

我认为非复制发送的目的是通过让数组的每个 View 都指向同一 block 内存来节省内存,但这并不是这里似乎就是这种情况。幕后发生了什么,我是如何误解非复制发送的使用的?

我上面的主要问题的背景是共享内存环境(我的笔记本电脑),但我有一个可能相关的问题是 numpy 数组的非复制发送如何工作以及它们在分布式内存情况下的用途是什么,其中计算节点是不同的物理机器,你必须(我假设)通过网络发送 numpy 数组(有效地在接收机器上制作副本),因此查看原始内存位置是没有意义的。

最佳答案

IPython.parallel(或底层 Zeromq)上下文中的非复制发送并不意味着与目标共享内存。IPython.parallel 不是基于共享内存系统,而是基于显式消息传递。

这意味着网络接口(interface)直接从您提供的数组中检索数据,而不是将数据复制到网络堆栈中自己的缓冲区中。到目标进程或线程的传输仍然始终是副本,即使它位于同一台机器上。

因此数据的接收方可以修改数据,而无需更改发送方的数据。但发送方必须注意,在将数据复制到目的地之前,不要修改它提供给网络接口(interface)的缓冲区。对于 pyzmq,这可以通过使用 track 关键字参数来完成,该参数为您提供一个对象,您可以轮询该对象以完成传输,并且缓冲区再次可用于修改。

非复制发送是一种危险的优化,因为您必须非常小心哪些缓冲区可用于写入,哪些缓冲区不可写入。仅当您明确指出网络堆栈的附加副本会造成性能问题时,才应使用它们。

关于python - ipython并行和非复制发送numpy数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28617271/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com