背景
在嵌入式平台中,为了节约存储空间、内存资源,通常需要降低目标bin文件的size。下面总结下code size的优化经验。本文所说的优化主要是指的C/C++代码binary/elf size。
统计工具
工欲善其事必先利其器,首先介绍一下统计工具。在优化可执行文件size之前,要先统计一下目标文件各个段的大小,先把引起size变大的原因拆解清楚再逐个寻找优化点。介绍几个优化工具和使用方法。
map文件
gcc/clang编译时加上-Wl,-Map=xxx.map可以生成map文件。通过map⽂件计算出某个全局变量、常量,函数代码段的size⼤⼩。map⽂件就是通过编译器编译、链接后之后生成的文件,包含函数入口地址、大小,全局变量地址、常量地址等⼀些重要信息。从map我们可以了解到:
- 程序各区段的size,即⽬前存储器的使⽤量
- 程序中各个symbol的地址
- 各个symbol在存储器中的顺序关系
- 可以大致看出哪些全局变量、函数代码过大。
- 注意map文件有可能和目标elf中的符号不一样,如在编译map文件时带了unused的符号,而生成目标文件时又去掉了unused符号。
bloaty
bloaty是google提供的一个工具,源码地址:项目首页 - bloaty - GitCode,可以从上面的链接中找到安装步骤和使用方法。
查看单个目标文件的size
bloaty可以统计生成二进制文件的每个源文件、函数的大小,很适合对比库文件、elf文件。
bloaty xxx.elf -s vm -d compileunits -n 0 > xxx_per_file_size.txt
$ ./bloaty bloaty -d compileunitsFILE SIZE VM SIZE -------------- -------------- 34.8% 10.2Mi 43.4% 2.91Mi [163 Others]17.2% 5.08Mi 4.3% 295Ki third_party/protobuf/src/google/protobuf/descriptor.cc7.3% 2.14Mi 2.6% 179Ki third_party/protobuf/src/google/protobuf/descriptor.pb.cc4.6% 1.36Mi 1.1% 78.4Ki third_party/protobuf/src/google/protobuf/text_format.cc3.7% 1.10Mi 4.5% 311Ki third_party/capstone/arch/ARM/ARMDisassembler.c1.3% 399Ki 15.9% 1.07Mi third_party/capstone/arch/M68K/M68KDisassembler.c3.2% 980Ki 1.1% 75.3Ki third_party/protobuf/src/google/protobuf/generated_message_reflection.cc3.2% 965Ki 0.6% 40.7Ki third_party/protobuf/src/google/protobuf/descriptor_database.cc2.8% 854Ki 12.0% 819Ki third_party/capstone/arch/X86/X86Mapping.