首页 > 解决方案 > 在对齐的内存缓冲区中为 capnp FlatArrayMessageReader 接收 zmq 消息

问题描述

PUB/SUB使用. tcp://_ capnp_ capnp::messageToFlatArray在接收方,我收到一条zmq_msg_t消息中的全部内容。但zmq_msg_data(&message)返回一个未capnp::word对齐的内存位置。FlatArrayMessageReader抛出内存未对齐的异常也是如此。

简化的代码如下所示:

    zmq_msg_t message;
    zmq_msg_init(&message);

    zmq_msg_recv(&message, socket, flags);

    size_t size = zmq_msg_size(&message);
    auto data = zmq_msg_data(&message);
    auto pdata = kj::arrayPtr((const capnp::word*)data, size / sizeof(capnp::word));
    capnp::FlatArrayMessageReader msg = capnp::FlatArrayMessageReader(pdata);  // exception

什么是在不复制整个缓冲区的情况下对齐数据的好方法?或者有没有办法在没有性能损失的情况下在字对齐的内存中接收消息 - 比如在 zmq 中禁用零复制?

尝试使用 capnp 版本 0.7.0、zeromq 版本 4.3.2 和 gcc 7.4.0 的 ubuntu 18.04。

标签: c++zeromqcapnproto

解决方案


什么是在不复制整个缓冲区的情况下对齐数据的好方法?

好吧,鉴于 ZeroMQ(按原样)基于一个自主工作的Context()实例引擎,出于同样的、出于性能动机的原因,它自己承诺了零拷贝,消息的存储位置由Context()内部决定不“看到”的政策越不“服从”任何capnp偏好。

除非一个人不仅重构zmq_msg_init() 本身,而且重构 ZeroMQ 内部所有相关的以性能为动机的内部性,以便在外部“强制”和“保持”某种(此处capnp为动机,导致典型的“利益冲突”)更高级别的灌输内存管理(对齐分配、重用和释放策略),对于已经成熟、聪明、苗条(原样)和正确的人来说,期望这种行为的可能性似乎为零大小、功能刚刚好配备的工具,旨在提供快速、最小延迟但几乎线性可扩展的消息传递/信令工具。

有没有办法在字对齐的内存中接收消息而不会降低性能 - 比如在 zmq 中禁用零复制?

AFAIK,从来没有遇到过“跨”已发布 API 的此类配置(从 v2.+ 到 2020/Q1 的 v4.3)

可以尝试扫描带有注释的源代码,任何这样的技巧都可能被放置在适当的位置。


推荐阅读