fprintf 的成本
我正在用 C++ 为一个平台开发一个嵌入式应用程序,该平台的代码/数据 RAM 有限,但文件系统使用的 RAM 却不受限制。
在寻求减少代码大小时,我意识到排除 fprintf() 行对生成代码的大小有很大影响。
我的问题是: 1.为什么fprintf的成本这么高? 2. 如果我排除 fprintf 功能,那么生成描述应用程序运行过程中发生的情况的日志文件的替代方法是什么?
I am developing an embedded application in C++ for a platform with limited code/data RAM, but rather unlimited RAM for filesystem usage.
While looking for reducing the code size, I realized that excluding fprintf() lines contributed a lot to the size of generated code.
My questions are :
1. Why is the cost of fprintf so high ?
2. If I exclude the fprintf functionality, what would be the alternative to generate log files describing the occurances through the application run ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
在嵌入式系统中,
printf
有时可以拖入对%f
等格式字符串的所有浮点支持。更智能的环境将使 printf 的浮点选项成为可选的东西。
但即使对于整数,
printf
中也有很多通用代码,您可能会发现根据您的特定需求编写自己的例程会更加紧凑,例如:依此类推,用于写入缓冲区,然后
outBuff (char *buff)
用于将其发送到文件或标准输出。例如,如果您控制正在使用的数据(无字符串溢出、16 位二进制补码整数等),则可以使用以下函数
:
运行此命令:
输出:
这些函数的大小应该相对较小,因为它们针对的是特定需求,而不是更通用的 printf 系列。
In embedded systems,
printf
can sometimes drag in all the floating point support for format strings like%f
.More intelligent environments will make the floating point options for
printf
an optional thing.But even for integers, there's a lot of general purpose code in
printf
and you may find it's more compact to write your own routines, tailored to your specific needs, like:and so on, for writing to buffers, then
outBuff (char *buff)
for sending it to a file or standard output.For example, if you control the data being used (no string overflow, 16-bit twos complement integers and such), you can use the following functions:
Running this with:
outputs:
These functions should be relatively small in size since they're targeted to specific needs rather than the far more general
printf
family.需要合理数量的代码来提供完整的 ANSI 兼容
printf
功能。一些嵌入式环境提供了几个不同版本的 printf,这些版本要小得多,因为它们只提供选定的功能。
例如,适用于 MSP430 的 IAR C/C++ 编译器 (PDF),提供 printf 格式化程序的 Tiny、Small、Large 和 Full 实现,以及 Tiny em> 版本仅支持基本说明符(
c、d、i、o、p、s、u、X、x 和 %
),不支持多字节、浮点数、长度修饰符、宽度和精确。如果您的环境提供此选择,请选择符合您需求的
printf
(和scanf
)版本,并注意其限制。如果您的环境不提供此选择,请查看各种可用的“tiny”替代
printf
实现(例如此来自 SpareTimeLabs 的 Kustaa Nyholm)。It takes a reasonable amount of code to provide the full ANSI compliant
printf
functionality.Some embedded environments offer several different versions of
printf
that are considerably smaller, as they only offer selected functionality.For example, the IAR C/C++ Compiler for MSP430 (PDF), offers Tiny, Small, Large and Full implementations of the printf formatter, with the Tiny version only supporting the basic specifiers (
c, d, i, o, p, s, u, X, x, and %
) with no support for multibytes, floats, length modifiers, width and precision.If your environment offers this choice then select the version of
printf
(andscanf
) that matches your needs and be aware of the limitations.If your environment does not offer this choice then take a look at the various "tiny" alternative
printf
implementations available (such as this one from Kustaa Nyholm of SpareTimeLabs).我可以想到三种情况:
在场景 1 中,罪魁祸首不是 fprintf,而是您传递给它的字符串文字。您需要从代码中获取这些字符串,方法是使用非常短、简洁的消息,或者将字符串存储在文件中并通过代码中某种形式的 ID 引用它们(尽管这会导致性能下降)。
在场景 2 中, fprintf(可能)是罪魁祸首。这是一个相当复杂的函数,能够以各种方式格式化各种数据类型 - 因此它需要相当多的代码空间。当您删除最后一次使用它时,链接器将从最终的二进制文件中删除它,使它们更小。尝试使用 std::ofstream 代替。如果您仅将(例如)整数和字符串插入到输出文件中,则仅链接处理整数和字符串的代码。
场景 3 不太可能出现 - 并且可能表明 fprintf 正在被内联 em> 无论你在哪里使用它。
希望这有帮助
I can think of three scenarios:
In scenario 1, it isn't fprintf that is the culprit, but rather the string literals that you are passing to it. You need to get these strings out of your code, either by using very short, terse messages, or by storing the strings in a file and referencing them by some form of ID within the code (although this incurs performance hits)
In scenario 2, fprintf is (probably) the main culprit. It is quite a complex function that is capable of formatting all kinds of data types in all kinds of ways - so it takes quite a bit of code space. When you remove the last use of it the linker will eliminate it from the final binaries, making them smaller. Try using std::ofstream instead. If you only ever insert (for example) ints and strings to your output file, then only the code for handling ints and strings is linked in.
Scenario 3 is very unlikely - and would probably indicate that fprintf is being inlined wherever you use it.
Hope this helps
第一个问题的答案取决于您使用的编译器;你只能通过检查你的编译器来得到明确的答案。正如 GrahamS 指出的那样,格式化程序的实现可能很复杂。
尝试使用
fputs
而不是fprintf
来避免格式化程序。The answer to your first question depends on the compiler that you are using; you can only get a definitive answer by examining your compiler. As GrahamS pointed out, formatter implementation can be complicated.
Try using
fputs
instead offprintf
to avoid the formatter.