【发布时间】:2020-01-24 16:18:45
【问题描述】:
有许多简单的教程以及 SO 问题和答案声称 Ray 以某种方式与工作人员共享数据,但这些都没有详细说明如何在哪个操作系统上共享数据。
例如在这个 SO 答案中:https://stackoverflow.com/a/56287012/1382437 一个 np 数组被序列化到共享对象存储中,然后被多个访问相同数据的工作人员使用(从该答案复制的代码):
import numpy as np
import ray
ray.init()
@ray.remote
def worker_func(data, i):
# Do work. This function will have read-only access to
# the data array.
return 0
data = np.zeros(10**7)
# Store the large array in shared memory once so that it can be accessed
# by the worker tasks without creating copies.
data_id = ray.put(data)
# Run worker_func 10 times in parallel. This will not create any copies
# of the array. The tasks will run in separate processes.
result_ids = []
for i in range(10):
result_ids.append(worker_func.remote(data_id, i))
# Get the results.
results = ray.get(result_ids)
ray.put(data) 调用将数据的序列化表示放入共享对象存储中,并为它传回句柄/id。
然后当worker_func.remote(data_id, i) 被调用时,worker_func 被传递反序列化的数据。
但是这两者之间究竟发生了什么?显然,data_id 用于定位数据的序列化版本并对其进行反序列化。
Q1:当数据“反序列化”时,是否总是会创建原始数据的副本?我想是的,但我不确定。
一旦数据被反序列化,它就会被传递给工作人员。现在,如果需要将相同的数据传递给另一个工作人员,有两种可能性:
Q2:当一个已经反序列化的对象被传递给一个工作者时,它是通过另一个副本还是完全相同的对象?如果它是完全相同的对象,这是否使用标准共享内存方法在进程之间共享数据?在 Linux 上,这意味着写时复制,那么这是否意味着一旦对象被写入,就会创建它的另一个副本?
Q3: 一些教程/答案似乎表明,根据数据类型(Numpy 与非 Numpy),反序列化和在工作人员之间共享数据的开销有很大不同,那么详细信息是什么?那里?为什么 numpy 数据共享更有效,并且当客户端尝试写入该 numpy 数组时这仍然有效(我认为这总是会为进程创建一个本地副本?)?
【问题讨论】:
标签: python numpy serialization shared-memory ray