我编写了一个在嵌入式处理器(ARM)上运行的算法的两种不同的C实现。我想用一种公平的方式比较这两种实现方式 代码大小,所以在下载可执行文件时,我得到以下数字:
Implementation One
.text size 55098 bytes
.data size 2048 bytes
Implementation Two
.text size 54598 bytes
.data size 2048 bytes
.text段的差异是500字节,但相对而言,它并不是很多。问题是,该图还包含围绕可执行文件的引导代码,以便可以在独立模式下调用它,即,在嵌入式处理器上没有操作系统。
我想知道是否有人知道我如何获得可执行文件的ACTUAL代码大小而没有所有膨胀的额外代码。
非常感谢 安德鲁
答案 0 :(得分:8)
要获取asm输出或映射文件,需要为编译器和/或链接器指定适当的选项。这些选项取决于您使用的工具链(编译器,链接器)。
从gcc获取asm输出: gcc -S -o hello_asm.s hello.c
答案 1 :(得分:2)
您的链接器几乎可以肯定地生成一个MAP文件(可能已经这样做了),它将显示(详细的)所有单个数据和代码对象的内存使用情况详细信息,当然还有对象模块级别,以及通常直到单个函数和数据对象级别。
答案 2 :(得分:1)
最后将下载所有代码,包括bootloader和OS。那么你为什么要将它们从措施中排除?
一种简单的方法,可以了解要排除的代码大小,以便尽可能简单地使用应用程序进行编译(例如main(){}
)。然后,您只需要从下一个度量中减去获得的值。
答案 3 :(得分:0)
您应该定义extra code
的一部分。希望你已经在另一个编译单元中编写了这个额外的代码。您的工具链应该有工具来检测编译单元的代码大小。
最重要的是,您应该将代码大小与availbale内存进行比较。如果您没有要求将代码放在指定的内存区域中,那么减少代码大小是不值得的。
答案 4 :(得分:0)
一种可能的方法是让构建工具以更精细的粒度转储映射。
例如,如果您使用的是gnu工具集,则可以在.elf文件上使用run size
,并根据其中的目标文件对其进行细分。
您还可以在.elf文件中使用objdump
来获取详细的地图。
假设示例中的bootcode在两个整体实现之间保持不变,使用这些工具可以让您更好地了解哪个具有更好的代码空间效率。
答案 5 :(得分:0)
如果您使用的是GNU工具,则可以使用size
工具。它将告诉您任何目标文件在每个部分中使用的内存量。在您的情况下,您需要确保要测量的代码位于其自己的文件中。
以下是输出的示例:
text data bss dec hex filename
9767 4 5184 14955 3a6b cfi_flash.o
1138 0 192 1330 532 cfi_mtd.o
556 0 128 684 2ac mtdcore.o
3897 0 8 3905 f41 mtdpart.o
答案 6 :(得分:0)
有时很难单独确定实现的大小,因为某些实现需要链接库例程,而其他实现则不需要。如果例程#1比#2小300字节,但需要500字节的库例程foo(),而例程#3比#4小300字节,但也需要相同的例程,那么#1隔离有效将是比#2大200(即500-300)个字节,隔离#3比#4大200个字节,但#1加#3比#2加#4小100个字节(因为库例程会只需要一次)。
如果某个库例程产生功能减少(并且成本降低)的替代方案,则经常会出现这种情况。如果可以避免使用昂贵的库例程,那么编写和使用更简单的版本是值得的。另一方面,如果代码最终使用昂贵的例程,那么更简单的版本可能最终是多余的。
答案 7 :(得分:0)
你可以编写一个“实现空”,它只有一个不执行任何操作的存根函数。这将为您提供在比较中使用的基线值。
(实施规模一,实施规模为空) 与 (实施规模二 - 实施规模为空)