我正在开发一个应尽可能少使用内存的库(我不关心其他任何东西,比如二进制大小或速度优化).
我可以使用任何GCC标志(或任何其他与GCC相关的选项)吗?我应该避免某种程度的-O*优化吗?
你的库 - 或者惯用的C-中的任何代码都有几种内存使用方式:
-Os应该优化它malloc; 你显然应该知道如何分配堆内存(以及后来的free-d).实际的内存消耗将取决于您的特定malloc实现(例如,许多实现,当调用malloc(25)实际上可能消耗32个字节),而不是在编译器上.顺便说一句,您可能会设计您的库以使用一些内存池,甚至可以实现您自己的分配器(在OS系统调用之上,如mmap上面malloc等等)-Os或者-O2用于gcc,可能会使用更多寄存器,并且在优化时可能会略微减少堆栈).您可以通过-fstack-usage来gcc要求它给出每个调用帧的大小,并且当调用帧超过len个字节时,您可能会给-Wstack-usage=len一个警告.nm或其他一些binutils程序来查询它们).顺便说一下,在函数内部仔细地声明一些变量static会降低堆栈消耗(但是你不能对每个变量或每个函数都这样做).另请注意,在某些有限的情况下,GCC正在进行尾调用,然后降低堆栈使用率(因为调用者的堆栈帧在被调用者中重用).(另见这个老问题).
您可能还会要求编译器打包一些特定的struct-s(注意,这可能会显着降低性能).你会想要使用某些类型属性,比如__attribute__((packed))......等等,也许还有一些变量属性 ......
也许您应该阅读有关垃圾收集的更多信息,因为GC技术,概念和术语可能是相关的.看到这个答案.
如果在Linux上,valgrind工具也应该是有用的......(在调试阶段-fsanitize=address,最近的GCC选项).
您可能也可能使用一些代码生成选项,如-fstack-reuse=或-fshort-enums或-fpack-struct或-fstack-limit-symbol=或-fsplit-stack; 要非常小心:一些这样的选项会使您的二进制代码与现有的C(和其他!)库不兼容(那么您可能需要使用libc相同的代码生成标志重新编译所有使用过的库,包括您的库).
你或许应该启用链接时优化的编译和链接用-flto(在另外的其他优化标志一样-Os).
你当然应该使用最新版本的GCC.请注意,GCC 5.1已于几天前发布(2015年4月).
如果您的库足够大,值得付出努力,您甚至可以考虑使用MELT自定义GCC编译器(以帮助您了解如何减少内存消耗).这可能需要数周或数月的工作.