C++高性能通信:了解Iceoryx与零拷贝技术的实现与应用

news2024/9/22 17:31:08

文章目录

    • 0. 引言
    • 1. Iceoryx使用到的零拷贝技术
      • 1.1 零拷贝技术概述
      • 1.2 零拷贝的优势
      • 1.3 Iceoryx零拷贝的实现
      • 1.4 信息轮询与信号触发
    • 2. Iceoryx的核心概念
      • 2.1 RouDi (iox-roudi)
      • 2.2 Runtime
      • 2.3 Publisher
      • 2.4 Subscriber
      • 2.5 Topic
    • 3. Iceoryx使用示例
      • 3.1 发布者程序
      • 3.2 订阅者程序
      • 3.3 编译和运行
      • 3.4 压力测试脚本
    • 4. 参考文章

0. 引言

Iceoryx是一个开源的实时通信框架,特别适用于需要高性能和低延迟的嵌入式系统,如自动驾驶系统、机器人控制、航空航天等。

详细介绍请看官网

img

iceoryx 使用真正的零拷贝共享内存方法,允许将数据从发布者传输到订阅者而无需任何副本。这可确保数据传输具有恒定的延迟,无论有效负载的大小是多少。

img
关于进程间通信,Iceoryx与Nanomsg的对比请看从 Nanomsg 到 Iceoryx: 发布-订阅模式的性能对比

1. Iceoryx使用到的零拷贝技术

1.1 零拷贝技术概述

零拷贝是指在数据传输过程中,避免不必要的数据拷贝操作。传统的数据传输通常涉及将数据从一个缓冲区复制到另一个缓冲区,这会产生额外的开销。而零拷贝技术允许数据在不进行拷贝的情况下直接传递到目标缓冲区,从而提高传输效率。

Iceoryx使用共享内存进行进程间通信,将数据放置在共享内存区域,然后通过指针引用实现数据传递,避免了数据的额外复制。

1.2 零拷贝的优势

  1. 减少CPU开销:零拷贝减少了CPU的复制操作,提高了系统性能。
  2. 降低内存占用:由于数据不需要在不同缓冲区之间复制,内存使用更为高效。
  3. 降低传输延迟:数据直接传递,无需复制等待时间。

1.3 Iceoryx零拷贝的实现

Iceoryx通过以下方式实现真正的零拷贝:

  • 利用共享内存技术,预先开辟内存块(chunk),publisher将数据写入。
  • Subscriber通过指针获取chunk中的信息,数据被写入时,subscriber收到一个指针。
  • Iceoryx维护每个chunk的引用记录,确保资源不被浪费。

1.4 信息轮询与信号触发

为了提升数据获取效率,Iceoryx提供两种方式:

  • WaitSet:采用react设计模式,绑定对应的subscribers,数据到来时触发通知。
  • Listener:直接触发用户定制的callback,数据到来时调用回调函数。

2. Iceoryx的核心概念

掌握以下核心概念对于理解和开发基于Iceoryx的通信功能至关重要:

2.1 RouDi (iox-roudi)

定义
RouDi是Iceoryx的中间件守护进程(daemon),负责管理和协调不同应用之间的通信。它是Iceoryx通信框架中的核心组件,所有使用Iceoryx的应用都需要与RouDi建立连接才能进行正常的数据交换。

功能

  • 路由与分发:RouDi作为中心节点,接收来自发布者的数据,并根据订阅者的需求将数据分发到相应的订阅者。
  • 资源管理与优化:管理共享内存资源,确保资源得到合理分配和回收,以提高系统性能和资源利用率。
  • 安全性与隔离:实施必要的安全措施,确保通信过程的安全性,并通过隔离机制防止不同应用之间的数据冲突。

使用
在启动任何使用Iceoryx的应用之前,必须先启动RouDi守护进程。

2.2 Runtime

定义
Runtime是Iceoryx为每个应用提供的运行时环境。在应用启动时,需要初始化其对应的Runtime,以便应用能够接入Iceoryx的通信框架。

功能

  • 初始化:为应用提供必要的初始化步骤,使其能够注册为Iceoryx通信框架的一部分。
  • 资源分配:为应用分配必要的资源,如共享内存段、消息队列等。
  • 通信管理:管理应用与其他参与者(如其他应用、RouDi等)之间的通信。

使用

constexpr char APP_NAME[] = "iox-publisher";
iox::runtime::PoshRuntime::initRuntime(APP_NAME);

2.3 Publisher

定义
Publisher是Iceoryx中的数据发送器,负责将数据发布到指定的Topic上,以便订阅者可以接收。

功能

  • 数据发送:将数据写入共享内存中的指定位置,并通知RouDi该数据已准备好被分发。
  • Topic绑定:Publisher需要与特定的Topic绑定,以便订阅者能够识别并接收其发布的数据。

使用

iox::popo::Publisher<Data> publisher({"Group", "Topic", "Instance"});

2.4 Subscriber

定义
Subscriber是Iceoryx中的数据接收器,负责订阅指定的Topic并接收来自发布者的数据。

功能

  • 数据接收:从共享内存中读取发布者发布的数据。
  • Topic绑定:Subscriber需要与特定的Topic绑定,以便接收该Topic上的所有数据。
  • 回调处理:当接收到新数据时,可以触发回调函数来处理数据。

使用

iox::popo::Subscriber<Data> subscriber({"Group", "Topic", "Instance"});

2.5 Topic

定义
Topic是Iceoryx中的数据载体,用于在发布者和订阅者之间传递数据。Publisher将数据发送到指定的Topic,而Subscriber则订阅该Topic以接收数据。

功能

  • 数据传递:作为数据传递的媒介,确保数据能够从发布者正确地传输到订阅者。
  • 命名约定:Topic通过组(Group)、主题(Topic)和实例(Instance)来唯一标识,以便发布者和订阅者能够准确匹配。

使用
在创建Publisher和Subscriber时,需要指定它们要绑定或订阅的Topic名称(包括组、主题和实例)。

3. Iceoryx使用示例

3.1 发布者程序

#include "iceoryx_posh/popo/publisher.hpp"
#include "iceoryx_posh/runtime/posh_runtime.hpp"
#include <chrono>
#include <thread>
#include <iostream>

struct Data {
    char message[128];
};

int main() {
    constexpr char APP_NAME[] = "iox-publisher";
    iox::runtime::PoshRuntime::initRuntime(APP_NAME);
    iox::popo::Publisher<Data> publisher({"Group", "Topic", "Instance"});

    while (true) {
        publisher.loan()
            .and_then([&](auto& sample) {
                std::strcpy(sample->message, "Hello from Publisher");
                sample.publish();
            })
            .or_else([](auto& error) {
                std::cerr << "Loaning sample failed: " << error << std::endl;
            });

        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }

    return 0;
}

3.2 订阅者程序

#include "iceoryx_posh/popo/subscriber.hpp"
#include "iceoryx_posh/runtime/posh_runtime.hpp"
#include <chrono>
#include <thread>
#include <iostream>

struct Data {
    char message[128];
};

int main() {
    constexpr char APP_NAME[] = "iox-subscriber";
    iox::runtime::PoshRuntime::initRuntime(APP_NAME);
    iox::popo::Subscriber<Data> subscriber({"Group", "Topic", "Instance"});

    while (true) {
        subscriber.take()
            .and_then([&](const auto& sample) {
                std::cout << "Received: " << sample->message << std::endl;
            })
            .or_else([](auto& error) {
                if (error != iox::popo::ChunkReceiveResult::NO_CHUNK_AVAILABLE) {
                    std::cerr << "Taking sample failed: " << error << std::endl;
                }
            });

        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }

    return 0;
}

3.3 编译和运行

确保已安装Iceoryx,并正确配置CMakeLists.txt:

cmake_minimum_required(VERSION 3.5)
project(IceoryxPubSub)

set(CMAKE_CXX_STANDARD 14)
find_package(iceoryx_posh REQUIRED)

add_executable(publisher_iceoryx publisher_iceoryx.cpp)
target_link_libraries(publisher_iceoryx iceoryx_posh::iceoryx_posh iceoryx_posh::iceoryx_posh_roudi_environment)

add_executable(subscriber_iceoryx subscriber_iceoryx.cpp)
target_link_libraries(subscriber_iceoryx iceoryx_posh::iceoryx_posh iceoryx_posh::iceoryx_posh_roudi_environment)

然后在项目根目录创建并运行CMake:

mkdir build
cd build
cmake ..
make

运行RouDi(Iceoryx的守护进程):

iox-roudi &

运行发布者和订阅者程序:

./publisher_iceoryx &
./subscriber_iceoryx &

3.4 压力测试脚本

#include <thread>
#include <vector>
#include <cstdlib>

void run_publisher() {
    system("./publisher_iceoryx");
}

void run_subscriber() {
    system("./subscriber_iceoryx");
}

int main() {
    const int num_publishers = 10;
    const int num_subscribers = 10;
    std::vector<std::thread> threads;

    for (int i = 0; i < num_publishers; ++i) {
        threads.emplace_back(run_publisher);
    }

    for (int i = 0; i < num_subscribers; ++i) {
        threads.emplace_back(run_subscriber);
    }

    for (auto& t : threads) {
        t.join();
    }

    return 0;
}

4. 参考文章

iceoryx源码阅读
iceoryx_github

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1947804.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

1万+台网络设备运维如何选择支撑工具?

针对1万台网络设备的运维管理&#xff0c;需要采取一套系统化、自动化且高效的管理方法与策略。“工欲善其事&#xff0c;必先利其器”&#xff0c;以下结合一些关键步骤探讨运维支撑软件工具的方案。 1 建立完善的设备档案 设备信息记录&#xff1a; 为每台设备建立详细的…

科研成果 | 高精尖中心取得高性能区块链交易调度技术突破

近日&#xff0c;未来区块链与隐私计算高精尖创新中心研究团队在区块链交易效率方面取得突破性进展&#xff0c;最新成果“高性能区块链交易调度引擎”首次为长安链带来高并行度的交易调度&#xff0c;充分利用现有计算资源&#xff0c;显著提升长安链交易处理速度。 随着区块…

安卓单机游戏:《植物大战僵尸:重生》一款深受玩家喜爱的塔防游戏

一款深受玩家喜爱的塔防游戏&#xff0c;在这个游戏中&#xff0c;玩家需要通过种植不同类型的植物来阻止不断涌来的僵尸入侵&#xff0c;而每种植物都有自己的能力与特点&#xff0c;游戏画面和音效都非常出色&#xff0c;剧情也十分有趣&#xff0c;难度不断升级&#xff0c;…

JAVA代码审计JAVA0基础学习(需要WEB基础知识)DAY2

JAVA 在 SQL执行当中 分为3种写法&#xff1a; JDBC注入分析 Mybatis注入分析 Hibernate注入分析 JDBC 模式不安全JAVA代码示例部分特征 定义了一个 sql 参数 直接让用户填入id的内容 一个最简单的SQL语句就被执行了 使用安全语句却并没有被执行 Mybatis&#xff1a; #…

第13周 简历职位功能开发与Zookeeper实战

第13周 简历职位功能开发与Zookeeper实战 本章概述1. Mysql8窗口函数over使用1.1 演示表结构与数据1.2 案例1:获取男女总分数1.3 案例2****************************************************************************************本章概述 1. Mysql8窗口函数over使用 参考案例…

行业不同怎么选企业管理咨询公司

在选择企业管理咨询公司时&#xff0c;不同行业的企业往往面临着各自独特的挑战和需求。因此&#xff0c;选择一家适合自身行业特点、能够提供专业且有针对性的咨询服务的管理咨询公司至关重要。本文将从行业差异的角度出发&#xff0c;探讨如何根据企业所在行业的不同&#xf…

二维码的生成与识别(python)

二维码生成 from PIL import Image import qrcode from qrcode.image.styledpil import StyledPilImage from qrcode.image.styles.colormasks import SolidFillColorMask from qrcode.image.styles.moduledrawers import SquareModuleDrawer# 创建二维码对象 qr qrcode.QRCo…

智能编程,一触即发:使用AIGC优化CSS——提升前端开发效率与质量

文章目录 一、AIGC在CSS优化中的应用场景智能代码生成自动布局调整性能优化建议样式和色彩建议 二、使用AIGC优化CSS的具体步骤明确需求选择AIGC工具输入描述或设计稿审查和调整集成和测试 三、AIGC优化CSS的优势与挑战优势&#xff1a;挑战&#xff1a; 《CSS创意项目实践&…

vue3前端开发-小兔鲜项目-登录和非登录状态下的模板适配

vue3前端开发-小兔鲜项目-登录和非登录状态下的模板适配&#xff01;有了上次的内容铺垫&#xff0c;我们可以根据用户的token来判定&#xff0c;到底是显示什么内容了。 1&#xff1a;我们在对应的导航组件内修改完善一下内容即可。 <script setup> import { useUserSt…

ATE测试设备ATECLOUD专注于电源模块、电源芯片和射频组件测试

在追求效率与精度的时代背景下&#xff0c;电子测试测量行业迎来了ATE自动化测试设备的革新。这一设备的出现&#xff0c;不仅简化了测试流程&#xff0c;还大幅提高了测试的准确性和速度。 新ATE自动化测试设备&#xff1a;ATECLOUD测试平台 纳米软件深耕电测行业16年&#xf…

算法 day4 【双指针、快慢指针、环形链表】链表下

⚡刷题计划day4继续&#xff0c;可以点个免费的赞哦~ 下一期将会开启哈希表刷题专题&#xff0c;往期可看专栏&#xff0c;关注不迷路&#xff0c; 您的支持是我的最大动力&#x1f339;~ 目录 ⚡刷题计划day4继续&#xff0c;可以点个免费的赞哦~ 下一期将会开启哈希表刷题…

无法连接网络打印机0x00000709原因分析及多种解决方法

在日常办公和生活中&#xff0c;打印机是不可或缺的重要设备。然而&#xff0c;有时在连接打印机的过程中&#xff0c;我们可能会遇到错误代码0x00000709的提示。有更新补丁导致的、有访问共享打印机服务异常、有访问共享打印机驱动异常等问题导致的&#xff0c;针对访问共享打…

实验三 FPGA使用Verilog HDL设计加法器

实验目的 掌握使用Vivado软件进行设计、综合、仿真、布线的方法。掌握FPGA程序的下载方法。掌握使用Verilog HDL设计加法器的方法。 实验要求 采用Verilog HDL语言设计加法器&#xff0c;实现两个4位数的相加运算&#xff0c;并将结果通过LED灯或数码管显示出来。对设计进行综…

如何通过集成软件授权管理系统推动企业业务增长?

软件货币化已经成为许多企业商业成功的关键&#xff0c;随着全球数字化进程不断深入&#xff0c;其重要性也在不断增加。将许可解决方案优化集成到现有系统中&#xff0c;已成为从接收到订单到交付和激活许可的任何高效流程的基本要素。 软件货币化无处不在 无论是传统的软件企…

[言简意赅] Matlab生成FPGA端rom初始化文件.coe

&#x1f38e;Matlab生成FPGA端rom初始化文件.coe 本文主打言简意赅。 函数源码 function gencoeInitialROM(width, depth, signal, filepath)% gencoeInitialROM - 生成 Xilinx ROM 初始化格式的 COE 文件%% 输入参数:% width - ROM 数据位宽% depth - ROM 数据深度% s…

在 LCD 上显示 png 图片-I.MX6U嵌入式Linux C应用编程学习笔记基于正点原子阿尔法开发板

在 LCD 上显示 png 图片 PNG 简介 无损压缩&#xff1a;PNG 使用 LZ77 派生算法进行无损压缩&#xff0c;确保图像质量不受损&#xff0c;且压缩比高 体积小&#xff1a;通过高压缩比&#xff0c;PNG 文件体积小&#xff0c;适合网络传输 索引彩色模式&#xff1a;PNG-8 格式…

Unity UGUI 之 RectTransform

本文仅作学习笔记与交流&#xff0c;不作任何商业用途 本文包括但不限于unity官方手册&#xff0c;唐老狮&#xff0c;麦扣教程知识&#xff0c;引用会标记&#xff0c;如有不足还请斧正 Unity - Manual: Rect Transform 1.Rect Transform是什么 2.轴心与锚点的映射关系 首先…

获取后端返回的图形验证码

如果后端返回的直接就是一个图形&#xff0c;有以下几种方式展示 一、直接在img标签里面的src里面调用接口 <img :src"dialogSrc" class"photo" alt"验证码图片" click"changeDialog">let orgUrl "/api/captcha" …

论文解读:DiAD之SG网络

目录 一、SG网络功能介绍二、SG网络代码实现 一、SG网络功能介绍 DiAD论文最主要的创新点就是使用SG网络解决多类别异常检测中的语义信息丢失问题&#xff0c;那么它是怎么实现的保留原始图像语义信息的同时重建异常区域&#xff1f; 与稳定扩散去噪网络的连接&#xff1a; S…

机器学习(二十):偏差和方差问题

一、判断偏差和方差 以多项式回归为例&#xff0c;红点为训练集数据&#xff0c;绿点为交叉验证数据。 下图的模型&#xff0c;训练集误差大&#xff0c;交叉验证集误差大&#xff0c;这代表偏差很大 下图的模型&#xff0c;训练集误差小&#xff0c;交叉验证集误差小&#x…