为什么GCC没有把这个打印优化为放入呢? [英] Why didn't GCC optimize this 'printf' to 'puts'?
问题描述
以下是我的测试代码:
#include<stdio.h>
static inline void foo(int a){
printf("%x
", a);
}
int main(void){
foo(0x1234);
return 0;
}
我觉得GCC应该意识到a
是文字整数,并优化成这样的代码:
puts("1234");
但我得到了以下汇编代码:
│0x8048341 <main+17> push $0x1234
│0x8048346 <main+22> push $0x80484e0
│0x804834b <main+27> push $0x1
│0x804834d <main+29> call 0x8048310 <__printf_chk@plt>
在我的项目中有很多这样的代码,因为我一直相信GCC会为我优化,甚至在一些可以简单地使用‘WRITE()’的上下文中,我坚持使用printf
,因为我认为我会从它的缓冲机制中受益。
现在我感到后悔,因为削减格式字符串的开销会扼杀我所获得的一切。我的项目中的这些代码级别很低,可能会造成性能瓶颈。
推荐答案
我的项目中的这些代码级别很低,可能会造成性能瓶颈。
首先,我可以减轻您对这不可能的担忧。控制台I/O的开销是巨大的(相对而言),因此无论您使用什么方法来执行,这都将始终是代码中的瓶颈。
我觉得GCC应该意识到
a
是文字整数,并优化成这样的代码:puts("1234");
显然不是。GCC(和Clang)是否执行printf("...
");
转换为puts("...");
的优化,如here所示,但这只在字符串文字与printf
一起使用时才会发生。优化器不会(当前)窥视格式字符串、解析它并围绕它进行优化。您调用了printf
,因此得到printf
。
编译器优化不是有保证的,因此您不应编写依赖的代码,除非首先验证在您感兴趣的所有情况下(包括代码变体、编译器版本、目标平台等)是否确实应用了所需的优化。
如果您想建议将此作为对GCC优化器的可能改进,您可以在their Bugzilla上建议改进。但不要指望它很快就会实施。考虑到预期的实际性能改进充其量是微乎其微的(见上文),实现这种类型的优化所需的逻辑并不真正值得努力。
同时,如果您绝对需要对代码进行最少更改即可进行此优化,则可以使用some macro hackery:
#define STRINGIFY_INTERNAL(x) #x
#define STRINGIFY(x) STRINGIFY_INTERNAL(x)
#define foo(a) puts(STRINGIFY(a))
这确实会产生所需的输出:
.LC0:
.string "0x1234"
MyFunction:
sub esp, 24
push OFFSET FLAT:.LC0
call puts
xor eax, eax
add esp, 28
ret
这篇关于为什么GCC没有把这个打印优化为放入呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!