32 kB的编译代码多少钱

时间:2010-08-22 21:23:31

标签: c++ c size arduino

我打算使用Arduino programmable board。那些具有相当有限的闪存,范围在16到128 kB之间,用于存储编译的C或C ++代码。

有没有办法估算它代表的(标准)代码的数量?

我认为这很模糊,但我只是在寻找一个数量级。

6 个答案:

答案 0 :(得分:6)

size命令的输出是一个很好的起点,但不会提供您需要的所有信息。

$ avr-size program.elf
text            data    bss     dec     hex filename

图像的大小通常比文本和数据部分的总和略大。 bss部分基本上是压缩的,因为它全是0。可能还有其他相关部分未按大小列出。

如果您的构建系统设置为我以前用于AVR微控制器的构建系统,那么您最终会得到* .elf文件以及* .bin文件,并且可能是* .hex文件。 * .bin文件是存储在处理器程序闪存中的实际图像,因此您可以检查其大小,以确定程序在编辑时的增长方式。 * .bin文件是使用objdump命令从* .elf文件中提取的,还有一些我现在还记不住的标志。

如果您想知道如何猜测您的C或C ++代码在编译时会产生多少,那么这将更加困难。当我尝试使用uint64_t而不是uint32_t时,我已经观察到函数中有10倍的爆炸,而我所做的只是递增它(这是我认为的代码的5倍左右)。这主要与gcc的avr优化不是最好的有关,但代码大小的较小变化可能会从看似无辜的代码中蔓延。

这可能会因使用C ++而放大,而C ++往往会隐藏更多变成代码的东西而不是C语言。 C ++隐藏的主要内容是析构函数调用和许多指针解除引用,它与对象中的this指针以及许多对象对其虚函数表和类静态变量的秘密指针有关。

在AVR上,所有这些指针内容都可能真正加起来,因为指针是寄存器的两倍,并且需要加载多个指令。此外,AVR只有几个可用作指针的寄存器对,这导致大量移动进出这些寄存器。

AVR小程序的一些提示:

  • 尽可能使用uint8_tint8_t代替int。如果您希望代码可移植,也可以使用uint_fast8_tint_fast8_t。这可能导致许多操作只占用一半的代码,因为int是两个字节。

  • 非常了解字符串和结构常量和文字以及它们的存储方式和位置。

  • 如果您不害怕,请阅读AVR组装手册。您可以了解指令的类型,并从中了解轻松映射到这些指令的C代码类型。使用那种C代码。

答案 1 :(得分:3)

你真的不能说那里。未编译代码的长度与编译代码的长度几乎没有关系。例如:

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

int main()
{
  std::vector<std::string> strings;
  strings.push_back("Hello");
  strings.push_back("World");
  std::sort(strings.begin(), strings.end());
  std::copy(strings.begin(), strings.end(), std::ostream_iterator<std::string>(std::cout, ""));
}

VS

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

int main()
{
  std::vector<std::string> strings;
  strings.push_back("Hello");
  strings.push_back("World");
  for ( int idx = 0; idx < strings.size(); idx++ )
    std::cout << strings[idx];
}

两者都是完全相同的行数,并产生相同的输出,但第一个例子涉及std :: sort的实例化,这可能比这里的其余代码多一个数量级的代码。

如果您绝对需要计算程序中使用的字节数,请使用汇编程序。

答案 2 :(得分:2)

下载arduino IDE并“验证”一些现有代码,或查看示例草图。它将告诉您代码的字节数,这将让您了解您可以在给定设备中放入多少字节。随机选取几个示例,web server示例为5816字节,LCD hello world为2616.两者都使用外部库。

答案 3 :(得分:2)

尝试创建应用的简化版本,首先关注最有价值的功能,然后开始添加'很好(和很酷)的东西'。验证代码时,请密切关注Arduino IDE中显示的字节使用情况。

作为一个粗略的指示,我的第一个应用程序(由推动按钮控制的LED闪光灯)需要1092个字节。 32k大约是1K。 C ++代码的足迹很小!

最让我担心的是RAM数量有限(1 Kb)。如果CPU堆栈占用了一些,那么创建任何数据结构都没有多少余地。

我只有48小时的Arduino,所以有效地使用它还有很多东西;-)但是使用起来很有趣:)。

答案 4 :(得分:1)

对于一个相当复杂的软件来说,这是相当多的,但如果你想让它具有很多不同的功能,你就会开始闯入极限。此外,如果你想存储相当多的静态字符串和数据,它可以很快地吃掉它。但是32 KB对于嵌入式应用来说是一个不错的数量。它往往是你首先遇到问题的RAM!

此外,嵌入式系统的C ++编译器通常比C编译器差很多。 也就是说,它们远不如普通桌面操作系统的C ++编译器(在为目标平台生成高效的机器代码方面)。

答案 5 :(得分:0)

在Linux系统中,您可以使用静态编译的示例程序进行一些实验。 E.g。

$ size `which busybox `
text            data    bss     dec     hex filename
1830468    4448   25650 1860566  1c63d6 /bin/busybox

大小以字节为单位。此输出独立于可执行文件格式,因为文件格式内不同部分的大小。文本部分包含机器代码和const stufff。数据部分包含用于静态初始化变量的数据。 bss大小是未初始化数据的大小 - 当然,未初始化的数据不需要存储在可执行文件中。)

好吧,busybox包含很多功能(比如所有常见的shell命令,shell等)。

如果您使用 gcc -static 链接自己的示例,请记住,您使用的libc可能会大大增加程序大小,并且使用嵌入式libc可能会更节省空间。

要测试您是否可以查看diet-libcuclibc并与之相关联。实际上,busybox通常与uclibc链接。

请注意,您通过这种方式获得的尺寸只能一个数量级。例如,您的工作站可能使用另一种CPU架构而不是arduino板,并且不同架构的机器代码可能或多或少地大小不同(因为操作数大小,可用指令,操作码编码等等)。

继续粗略的数量级推理,busybox大致包含309 tools(包括ftp守护程序等等),即busybox工具的平均代码大小约为5k。