我对Arrow Streaming感到困惑。许多描述Arrow的资料只是改写following
箭头存储器格式支持零拷贝读取
并且说Arrow是零复制工具。
但是据我了解these paragraphs:
以柱状格式的序列化数据的原始单位是“记录批”。从语义上讲,记录批是数组的有序集合,称为数组的字段,每个数组的长度彼此相同,但数据类型可能不同。记录批的字段名称和类型共同构成该批的架构。
在本节中,我们定义了一种协议,用于将记录批处理序列化为二进制有效负载流,并从这些有效负载中重建记录批处理而无需进行内存复制。
IPC Streaming Format的描述,以及我的有限理解,是对源,数据进行序列化,并且只有反序列化是零复制。
换句话说-使用Arrow Streaming的系统实际上正在复制数据。
正确吗?
正如您所说,Arrow在接收方总是零拷贝。
使用Arrow Streaming的系统实际上正在复制数据。
这取决于您所说的“复制”。数据是否在同一过程中在内存中复制?否。必须以某种方式将字节从一个虚拟地址空间传输到另一个虚拟地址空间,无论您是否认为从技术上讲它构成“副本”都取决于您的应用程序(也许还有观点)。
这里是实际的C ++代码(在撰写本文时),其中发送方将数据写入到OutputStream
中,该数据是接收方的代理
// Now write the buffers
for (size_t i = 0; i < payload.body_buffers.size(); ++i) {
const std::shared_ptr<Buffer>& buffer = payload.body_buffers[i];
int64_t size = 0;
int64_t padding = 0;
// The buffer might be null if we are handling zero row lengths.
if (buffer) {
size = buffer->size();
padding = BitUtil::RoundUpToMultipleOf8(size) - size;
}
if (size > 0) {
RETURN_NOT_OK(dst->Write(buffer));
}
if (padding > 0) {
RETURN_NOT_OK(dst->Write(kPaddingBytes, padding));
}
}
这里没有被强行复制的内容。如果dst
站在类套接字接口的前面,则这些字节会立即(或通过缓冲,或OutputStream
所做的任何事情)直接发送到接收器。如果dst
是文件句柄,则将字节写入文件等。