在C ++中优化空间而不是速度

当你说“优化”时,人们往往会认为“速度”。 但是嵌入式系统的速度并不是那么重要,但内存是一个主要的限制因素呢? 什么是一些指导方针,技巧和技巧可用于削减ROM和RAM中的额外千字节? 一个“配置文件”代码如何查看内存膨胀的位置?

PS有人可能会争辩说,在嵌入式系统中过早地优化空间并不是那么糟糕,因为你为数据存储和蠕变提供了更多的空间。 它还允许您降低硬件生产成本,因为您的代码可以在较小的ROM / RAM上运行。

PPS也欢迎参考文章和书籍!

PPPS这些问题密切相关:404615,1561629


我的经验来自一个非常有限的嵌入式内存环境:

  • 使用固定大小的缓存。 不要使用指针或动态分配,因为它们有太多开销。
  • 使用最小的int数据类型。
  • 永远不要使用递归。 始终使用循环。
  • 不要传递大量的函数参数。 改用全局变量。 :)

  • 你可以做许多事情来减少你的记忆足迹,我相信人们已经写了关于这个主题的书籍,但其中一些主要的是:

  • 编译器选项以减少代码大小(包括-Os和包装/对齐选项)

  • 链接器选项去除死代码

  • 如果您从闪存(或ROM)加载到RAM以执行(而不是从闪存执行),请使用压缩的闪存映像,并使用引导加载程序对其进行解压缩。

  • 使用静态分配:堆是分配有限内存的低效方式,并且如果它受限制可能由于碎片而失败。

  • 用于查找堆栈高水印的工具(通常它们用堆栈填充堆栈,执行程序,然后查看模式的剩余位置),因此您可以优化地设置堆栈大小

  • 当然,优化用于内存占用的算法(通常以速度为代价)


  • 一些明显的

  • 如果速度不重要,请直接从闪存执行代码。
  • 使用const声明常量数据表。 这将避免数据从闪存复制到RAM
  • 使用最小的数据类型紧密打包大数据表,并按正确顺序避免填充。
  • 对大量数据使用压缩(只要压缩代码不超过数据)
  • 关闭异常处理和RTTI。
  • 有人提到使用-Os? ;-)
  • 将知识折叠成数据

    Unix哲学的一个规则可以帮助使代码更紧凑:

    表示规则:将知识叠加到数据中,因此程序逻辑可能很愚蠢和强大。

    我无法计算我已经看到了多少次精心设计的分支逻辑,跨越多个页面,这些页面可能已经被折叠成规则,常量和函数指针的紧凑表格。 状态机通常可以用这种方式表示(状态模式)。 命令模式也适用。 这完全是关于编程的声明式和命令式编程。

    日志代码+二进制数据,而不是文本

    而不是记录纯文本,记录事件代码和二进制数据。 然后使用“短语手册”重新构建事件消息。 短语集中的消息甚至可以包含printf样式的格式说明符,以便事件数据值在文本中整齐地显示。

    尽量减少线程数量

    每个线程都需要它自己的内存块以用于堆栈和TSS。 在不需要抢占的地方,考虑在同一线程内合作执行任务(协作式多任务)。

    使用内存池而不是囤积

    为了避免堆碎片,我经常看到单独的模块为自己的用途囤积大量的静态内存缓冲区,即使偶尔需要内存。 可以使用内存池,以便内存仅在“按需”使用。 但是,这种方法可能需要仔细分析和检测,以确保池在运行时不会耗尽。

    仅在初始化时动态分配

    在只有一个应用程序无限期运行的嵌入式系统中,您可以以合理的方式使用不会导致碎片的动态分配:只需在各种初始化例程中动态分配一次,并且永不释放内存。 reserve()你的容器到正确的容量,不要让它们自动增长。 如果您需要频繁分配/释放数据缓冲区(例如,用于通信数据包),请使用内存池。 我曾经甚至扩展了C / C ++运行时,以便在初始化序列后尝试动态分配内存时它会中止我的程序。

    链接地址: http://www.djcxy.com/p/6731.html

    上一篇: Optimizing for space instead of speed in C++

    下一篇: Is it premature optimization to develop on slow machines?