紧急通知:禁止一切关于政治&VPN翻墙等话题,发现相关帖子会立马删除封号
小鱼 ROS 2 新书上线!点击链接查看, 新书配套视频点击链接查看。
提问前必看的发帖注意事项—— 提问前必看!不符合要求的问题拒绝回答!!
社区使用指南—如何添加标签修改密码
小鱼 ROS 2 新书上线!点击链接查看, 新书配套视频点击链接查看。
提问前必看的发帖注意事项—— 提问前必看!不符合要求的问题拒绝回答!!
社区使用指南—如何添加标签修改密码
消息订阅节点CPU异常高
-
定义了一个自定义消息,格式如下,
int32 frame_type int32 data_size int16 cipv uint8[20000000] raw_data uint32 DATA_MAX_SIZE=20000000
想使用共享内存,基于上述消息格式写了一个消息publish和subscription,发现subscription的CPU异常高,subscription中只做了订阅,没做其它数据处理,使用共享内存CPU应该不至于这么,这个可能是什么原因导致的呢
-
在使用共享内存进行消息发布(publish)和订阅(subscription)时,如果发现订阅节点的CPU异常高,即使订阅节点未进行复杂的数据处理,可能的原因包括以下几个方面:
-
共享内存访问冲突:
- 锁竞争:如果发布和订阅操作没有正确地管理共享内存的访问(例如,使用了不恰当的锁机制),可能会导致频繁的锁竞争,从而增加CPU的消耗。
- 读写冲突:共享内存的读写操作如果没有设计得当,可能会导致读写冲突,尤其是在高频率的消息发布和订阅场景下。
-
内存拷贝效率:
- 大量数据拷贝:如果每次消息发布后,订阅节点都需要从共享内存中拷贝大量数据(如20MB的
raw_data
),即使不做处理,拷贝本身也会消耗大量CPU资源。 - 拷贝方式:内存拷贝的方式(如是否使用了优化的内存拷贝函数)也会影响性能。
- 大量数据拷贝:如果每次消息发布后,订阅节点都需要从共享内存中拷贝大量数据(如20MB的
-
消息处理逻辑:
- 轮询频率:订阅节点可能以非常高的频率轮询共享内存以检查是否有新消息,这会导致CPU资源的浪费。
- 无效等待:如果订阅节点在没有新消息时仍然进行无效等待或轮询,也会导致CPU占用率高。
-
系统资源限制:
- 上下文切换:如果发布和订阅在不同的进程或线程中运行,频繁的上下文切换也可能导致CPU资源消耗。
- 缓存一致性:共享内存的使用可能导致缓存一致性问题的处理开销,尤其是在多核处理器环境中。
-
实现细节:
- 代码效率:订阅节点的代码实现可能存在效率低下的问题,例如使用了低效的数据结构或算法。
- 库函数选择:使用的库函数或API可能不是最优选择,导致性能瓶颈。
解决方案建议:
-
优化锁机制:
- 使用无锁数据结构或更高效的锁机制(如读写锁)来减少锁竞争。
- 确保锁的使用尽可能短暂和精确。
-
减少内存拷贝:
- 考虑使用指针或引用直接访问共享内存中的数据,而不是每次都进行拷贝。
- 使用优化的内存拷贝函数(如
memcpy_s
在Windows上,或特定于平台的优化版本)。
-
调整消息处理逻辑:
- 使用事件驱动或通知机制来减少轮询频率。
- 引入睡眠或等待机制,在没有新消息时减少CPU的占用。
-
优化系统资源使用:
- 考虑将发布和订阅操作放在同一进程内,以减少上下文切换。
- 使用合适的硬件和操作系统设置来优化缓存一致性。
-
代码和库优化:
- 审查并优化订阅节点的代码实现,确保使用高效的数据结构和算法。
- 评估并更换可能导致性能瓶颈的库函数或API。
通过上述方法,可以逐步定位并解决订阅节点CPU异常高的问题。
以上为生成回答,仅供参考~
-
-
消息订阅代码如下
encode_subscription_ = node_->create_subscription<roscpp_tutorials::msg::VideoEncodedData>( encode_topic, qos, [this](roscpp_tutorials::msg::VideoEncodedData::UniquePtr msg) { auto cur_time = GetSystemSynchronizedTimestamp(); auto diff = cur_time - msg->msg_header.timestamp; std::cout << "on VideoEncodedData: " << msg->msg_header.sequence_num << " " << diff << " " << msg->raw_data.size() << std::endl; });
-
@734741837 给出完整代码,看看是否设置成功