有许多简单的教程,还有一些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上,这意味着写时复制,这是否意味着在对象被写入后立即创建该对象的另一个副本?
第3季度:一些教程/答案似乎表明,根据数据类型(numpy与非numpy),在工作人员之间反序列化和共享数据的开销有很大不同,所以那里的细节是什么?为什么客户端尝试写入该numpy数组(我认为它将始终为该进程创建本地副本?)时,为什么numpy数据共享的效率更高,并且仍然有效?