Emi*_*ier 42 c++ embedded optimization
当你说"优化"时,人们倾向于认为"速度".但是速度并不是那么关键的嵌入式系统呢,但内存是一个主要的限制因素呢?什么是一些指南,技术和技巧可用于削减ROM和RAM中的额外千字节?一个"配置文件"代码如何查看内存膨胀的位置?
PS One可能会争辩说,在嵌入式系统中"过早地"优化空间并不是那么邪恶,因为你给自己留下了更多的数据存储空间和功能蠕变.它还允许您降低硬件生产成本,因为您的代码可以在较小的ROM/RAM上运行.
PPS也欢迎参考文章和书籍!
Tim*_*ith 30
我从极其受限的嵌入式内存环境中获得的经验:
Jam*_*mes 13
你可以做很多事情来减少你的记忆足迹,我相信人们已经有关于这个主题的书籍,但是一些主要的是:
编译器选项以减少代码大小(包括-Os和打包/对齐选项)
用于去除死代码的链接器选项
如果您从闪存(或ROM)加载到ram执行(而不是从闪存执行),则使用压缩的闪存映像,并使用引导加载程序对其进行解压缩.
使用静态分配:堆是一种分配有限内存的低效方法,如果它受到约束,则可能由于碎片而失败.
查找堆栈高水印的工具(通常它们用模式填充堆栈,执行程序,然后查看模式保留的位置),这样您就可以最佳地设置堆栈大小
当然,优化用于内存占用的算法(通常以牺牲速度为代价)
Emi*_*ier 12
const
.这样可以避免数据从闪存复制到RAMUnix哲学的规则之一可以帮助使代码更紧凑:
表示规则:将知识折叠成数据,因此程序逻辑可以是愚蠢和健壮的.
我无法计算有多少次我看到精心设计的分支逻辑,跨越许多页面,可以折叠成一个很好的紧凑的规则,常量和函数指针表.状态机通常可以这种方式表示(状态模式).命令模式也适用.这完全是关于声明性和命令式编程风格.
而不是记录纯文本,记录事件代码和二进制数据.然后使用"短语手册"重新构建事件消息.短语中的消息甚至可以包含printf样式的格式说明符,以便事件数据值在文本中整齐地显示.
每个线程都需要它自己的内存块用于堆栈和TSS.如果您不需要抢占,请考虑让您的任务在同一个线程内协同执行(协作多任务).
为了避免堆碎片,我经常看到单独的模块囤积大型静态内存缓冲区供自己使用,即使只是偶尔需要内存.可以使用内存池,因此内存仅"按需"使用.但是,这种方法可能需要仔细分析和检测,以确保池在运行时不会耗尽.
在只有一个应用程序无限期运行的嵌入式系统中,您可以以一种不会导致碎片的合理方式使用动态分配:只需在各种初始化例程中动态分配一次,并且永远不会释放内存.reserve()
你的容器到正确的容量,不要让它们自动生长.如果需要频繁分配/释放数据缓冲区(例如,对于通信数据包),则使用内存池.我甚至扩展了C/C++运行时,以便在初始化序列之后尝试动态分配内存时,它会中止我的程序.
与所有优化一样,首先优化算法,然后优化代码和数据,最后优化编译器.
我不知道你的程序是做什么的,所以我不能对算法提出建议.许多人都写过关于编译器的文章.所以,这里有一些关于代码和数据的建议: