公平比较代码大小

时间:2011-02-18 08:10:16

标签: c embedded size

我编写了一个在嵌入式处理器(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代码大小而没有所有膨胀的额外代码。

非常感谢 安德鲁

8 个答案:

答案 0 :(得分:8)

  1. 您的C编译器通常可以生成您可以检查的汇编源代码。
  2. 另一种可能性是从链接器查看映射文件,它应该为您提供各个函数的大小。
  3. 您可以使用调试器查看二进制代码。
  4. 要获取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)

你可以编写一个“实现空”,它只有一个不执行任何操作的存根函数。这将为您提供在比较中使用的基线值。

(实施规模一,实施规模为空) 与 (实施规模二 - 实施规模为空)