首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >谷物和促进序列化使用零拷贝吗?

谷物和促进序列化使用零拷贝吗?
EN

Stack Overflow用户
提问于 2017-01-23 08:21:30
回答 2查看 2.2K关注 0票数 19

我在几种序列化协议(包括FlatBuffers、Cap、Boost序列化和谷物)之间做了一些性能比较。所有的测试都是用C++编写的。

我知道FlatBuffers和船长使用零拷贝。对于零拷贝,序列化时间为空,但序列化对象的大小更大.

我以为麦片和升级版没有使用零拷贝。但是,序列化时间(对于int和double)几乎为空,序列化对象的大小与Cap或Flatbuffers大小几乎相同。我在他们的文件里没有找到任何关于零拷贝的信息。

谷物和促进序列化也使用零拷贝吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-01-23 23:24:09

Boost and Cereal do not实现零拷贝,意义上是船长、Proto或Flatbuffers。

对于真正的零拷贝序列化,内存对象的备份存储实际上与传递给read()write()系统调用的内存段完全相同。根本没有包装/拆包步骤。

一般而言,这有若干影响:

  • 对象不使用new/delete分配。在构造消息时,首先分配消息,这将为消息内容分配一个长的连续内存空间。然后将消息结构直接分配到消息中,接收指向消息内存的指针。稍后编写消息时,一个write()调用就会将整个内存空间挤出线路。
  • 类似地,当您在消息中读取时,单个read()调用(或者可能是2-3)将整个消息读入一个内存块。然后,您将得到一个指向消息“根”的指针(或类似指针的对象),您可以使用该指针遍历消息。注意,在应用程序遍历消息之前,不会实际检查消息的任何部分。
  • 对于普通套接字,数据的唯一副本发生在内核空间中。有了RDMA网络,您甚至可以避免内核空间的拷贝:数据从线路上直接进入其最终的内存位置。
  • 当使用文件(而不是网络)时,可以直接从磁盘mmap()一条非常大的消息,并直接使用映射的内存区域。这样做是O(1) --不管文件有多大。当您实际访问该文件时,您的操作系统将自动在文件的必要部分中页面。
  • 同一台机器上的两个进程可以通过没有副本的共享内存段进行通信。注意,通常,常规的旧C++对象在共享内存中不能很好地工作,因为内存段在两个内存空间中通常没有相同的地址,因此所有指针都是错误的。使用零拷贝序列化框架,指针通常表示为偏移,而不是绝对地址,因此它们与位置无关。

Boost和Cereal是不同的:当您在这些系统中接收到一条消息时,首先对整个消息执行一次传递,以“解压缩”内容。数据的最后休息位置是使用new/delete以传统方式分配的对象。类似地,在发送消息时,必须从这个对象树中收集数据,并将其打包到一个缓冲区中,以便写入。尽管Boost和Cereal是“可扩展的”,但真正的零拷贝需要一个非常不同的底层设计;它不能作为扩展被栓入。

尽管如此,不要认为零拷贝总是会更快。memcpy()可以非常快,您的程序的其余部分可能会使成本相形见绌。同时,零拷贝系统往往有不方便的API,特别是由于内存分配的限制。总的来说,更好地利用您的时间使用传统的序列化系统。

零拷贝最明显的优势是在操作文件时,因为正如我所提到的,您可以轻松地mmap()一个巨大的文件,并且只读取其中的一部分。非零拷贝格式根本无法做到这一点。然而,当涉及到网络时,优势就不那么明显了,因为网络通信本身必然是O(n)。

最后,如果您真的想知道哪个序列化系统对于您的用例来说是最快的,那么您可能需要全部尝试并测量它们。请注意,玩具基准通常具有误导性;您需要测试实际用例(或类似的东西)才能获得有用的信息。

公开:我是Cap(一个零拷贝序列化程序)和协议缓冲区v2 (一个流行的非零拷贝序列化程序)的作者。

票数 28
EN

Stack Overflow用户

发布于 2017-01-23 11:09:41

注:我给出了另一个答案,它能更好地理解问题的全部含义。

Boost序列化是可扩展的。

它允许您的类型描述需要序列化的内容,以及描述格式的归档。

这可以是“零拷贝”--也就是说,唯一的缓冲是在接收数据的流中(例如套接字或文件描述符)。

有关dynamic_bitset序列化的有意识的零拷贝实现的示例,请参阅答案:bitset?中的代码。

我在网站上有很多这样的东西。还请看一下BOOST_IS_BITWISE_SERIALIZABLE的文档及其对容器序列化的影响(如果序列化一个连续分配的位序列化数据集合,其结果是零拷贝,甚至是__memcpy_sse4等等)。

附带注意: proto船长完全是在做其他的事情,AFAIK:它将一些对象作为未来的数据。这显然是他们大肆宣传的"∞%快,0!“(在从未检索数据的情况下,这在某种程度上是正确的)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41801826

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档