不使用堆内存的高速 CAN 数据处理
Posted
技术标签:
【中文标题】不使用堆内存的高速 CAN 数据处理【英文标题】:High speed CAN data processing without using heap memory 【发布时间】:2019-03-18 13:07:03 【问题描述】:我有一个情况:
基本上有3个模块命名为'A','B','C'。 每个模块都涉及多线程。
模块'A'获取高速数据(20ms)并发送。模块“B”的线程之一拾取。
模块'B'提取相关数据并进行一些位操作活动并广播它,以便模块'C'的任何一个线程拾取并执行自己的活动。
现在假设模块“B”中的数据在处理时需要一些位操作,当我们发送数据时,每个 CAN(控制器区域网络)数据都会使用堆分配,因为每个数据都有自己的内存,因此每次数据(20ms)进入 B 模块时,都会创建一个堆内存。因此,堆使用量很大。
我不能使用局部变量,因为其他模块不知道它。
我也尝试使用静态/全局,但缺点是因为数据很快。当静态变量获取数据并传递给将要广播的函数时,数据可能会更新为新值(并且可能会丢失数据)。
我也不能使用锁定系统,因为每个模块都会有不同的线程并且上下文也不相同。
有什么办法,可以避免使用动态内存分配?
如果有人不完全理解,请告诉我,我将尝试重新提出问题。请原谅我的英语
【问题讨论】:
您可以考虑使用内存池和自定义分配器。或者你可以提前分配一大块,然后用“placement new”自己管理内存。当然,这些方法伴随着您自己实施和维护这些复杂但基础系统的难题。 @metal 你能详细说明一下吗,因为我得到的是它。一个内存池从内核中取出一次,然后分别在每个数据中分配(这就是您所说的自定义分配器)。 我建议在谷歌上搜索“C++ 自定义分配器内存池”。搜索我的第一个链接是good one。看看这个。如果您有更具体的问题,请随时提出。 如果你的线程之间交换的对象都是一致的,预先知道的大小,那么也许你可以使用 object pool 而不是更通用的内存池使用自定义分配器。 @VBurman,无论您做什么,您都无法长时间适应数据到达速度快于处理速度的情况,至少不能没有数据丢失。通过某种程度的动态分配,您可以在一定程度上适应流量高峰,而无需在其余时间保持较大的内存占用,但持续的超额订阅将继续要求越来越多的内存,除非您减轻一些负载。 【参考方案1】:你问:
有什么办法可以避免大量使用动态内存分配? (编辑我的)
是的,但是除了指向一个解决方案之外,还有很多方法可以做到这一点。
最简单的可能是标准库容器,然后使用它们的reserve
(参见https://en.cppreference.com/w/cpp/container/vector/reserve)功能(或仅依赖指数增长)。
https://en.cppreference.com/w/cpp/container
我猜你会寻找vector 或unordered-map 来满足你的需求。
https://en.cppreference.com/w/cpp/container/vector
https://en.cppreference.com/w/cpp/container/unordered_map
有助于解决此类问题的其他概念包括 circular-buffer 或 memory-pool
【讨论】:
以上是关于不使用堆内存的高速 CAN 数据处理的主要内容,如果未能解决你的问题,请参考以下文章
Linux 内核 内存管理内存管理架构 ③ ( Linux 内核中的内存管理模块 | 页分配器 | 不连续页分配器 | 内存控制组 | 硬件设备内存管理 | MMU | 页表缓存 | 高速缓存 )