为什么GCC没有把这个打印优化为放入呢? [英] Why didn't GCC optimize this 'printf' to 'puts'?

查看:13
本文介绍了为什么GCC没有把这个打印优化为放入呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下是我的测试代码:

#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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆