C++ 谷物和Boost系列化是否使用零拷贝?
我已经对几种序列化协议进行了性能比较,包括FlatBuffers、Cap'n Proto、Boost序列化和Groove。所有的测试都是用C++编写的。 我知道FlatBuffers和Cap'n Proto使用零拷贝。对于零拷贝,序列化时间为空,但序列化对象的大小更大 我以为谷类食品和Boost系列化没有使用零拷贝。但是,序列化时间(对于int和double)几乎为null,序列化对象的大小几乎与Cap'n Proto或Flatbuffers对象的大小相同。我在他们的文档中没有找到任何关于零拷贝的信息 谷物和Boost系列化也使用零拷贝吗 注:我给出了另一个更能理解问题全部范围的答案 Boost序列化是可扩展的 它允许您的类型描述需要序列化的内容,并允许归档描述格式 这可以是“零拷贝”-即,唯一的缓冲是在接收数据的流中(例如套接字或文件描述符) 有关动态位集序列化的有意识零拷贝实现的示例,请参见此答案中的代码: 我在网站上有很多这样的东西。还可以查看文档,了解它对容器序列化的影响(如果序列化连续分配的按位可序列化数据集合,结果是零拷贝,甚至是C++ 谷物和Boost系列化是否使用零拷贝?,c++,serialization,boost,copy,cereal,C++,Serialization,Boost,Copy,Cereal,我已经对几种序列化协议进行了性能比较,包括FlatBuffers、Cap'n Proto、Boost序列化和Groove。所有的测试都是用C++编写的。 我知道FlatBuffers和Cap'n Proto使用零拷贝。对于零拷贝,序列化时间为空,但序列化对象的大小更大 我以为谷类食品和Boost系列化没有使用零拷贝。但是,序列化时间(对于int和double)几乎为null,序列化对象的大小几乎与Cap'n Proto或Flatbuffers对象的大小相同。我在他们的文档中没有找到任何关于零拷贝
\uu memcpy\u sse4
等)
旁注:Cap'nproto完全做了其他事情,AFAIK:它封送一些对象作为数据的未来。这显然是他们大肆宣传的内容。”∞% 更快,0µs!!!”(在从未检索到数据的情况下,这在某种程度上是正确的)
Boost和Score不执行Cap'n Proto或Flatbuffers意义上的零拷贝 使用真正的零拷贝序列化,live in memory对象的备份存储实际上与传递给
read()
或write()
系统调用的内存段完全相同。根本没有包装/拆包步骤
一般来说,这有许多含义:
- 不使用“新建/删除”分配对象。构造消息时,首先分配消息,这将为消息内容分配一个长的连续内存空间。然后直接在消息内部分配消息结构,接收实际上指向消息内存的指针。当消息稍后被写入时,一个
调用会将整个内存空间推到电线上write()
- 类似地,当您读入一条消息时,一个
调用(或者2-3)会将整个消息读入一块内存中。然后获得指向消息“根”的指针(或类似指针的对象),您可以使用它来遍历消息。请注意,在应用程序遍历消息之前,不会实际检查消息的任何部分read()
- 对于普通套接字,数据的唯一拷贝发生在内核空间中。使用RDMA网络,您甚至可以避免内核空间拷贝:数据直接从线路上传输到其最终内存位置
- 使用文件(而不是网络)时,可以直接从磁盘
发送非常大的消息,并直接使用映射的内存区域。这样做是O(1)——不管文件有多大。当您实际访问文件的必要部分时,操作系统将自动分页这些部分mmap()
- 同一台机器上的两个进程可以通过共享内存段进行通信,而不需要拷贝。注意,一般来说,普通的C++对象在共享内存中不太好,因为内存段通常在两个内存空间中没有相同的地址,因此所有指针都是错误的。对于零拷贝序列化框架,指针通常表示为偏移量而不是绝对地址,因此它们是位置独立的
memcpy()
可以非常快,程序的其余部分可能会使成本相形见绌。同时,零拷贝系统往往有不方便的API,特别是由于内存分配的限制。总体而言,使用传统的序列化系统可能会更好地利用您的时间
零拷贝最明显的优势是在操作文件时,因为正如我提到的,您可以轻松地mmap()
一个大文件,并且只读取其中的一部分。非零拷贝格式根本无法做到这一点。然而,当涉及到网络时,优势就不那么明显了,因为网络通信本身必然是O(n)
最后,如果您真的想知道哪种序列化系统对于您的用例来说最快,您可能需要全部尝试并测量它们。注意,玩具基准通常是误导性的;您需要测试您的实际用例(或非常类似的东西)以获得有用的信息
披露:我是Cap'n Proto(一个零拷贝序列化程序)和Protocol Buffers v2(一个流行的非零拷贝序列化程序)的作者。对不起,我很难理解boost序列化是如何实现零拷贝的。仅仅具有可扩展性是不够的:零拷贝需要一种完全不同的数据类型