编译器是否会通过将其移出循环来优化循环中的条件语句?

时间:2013-06-13 09:34:38

标签: c optimization gcc

这是C代码:

struct node{
    void *value;
    struct node *next;
};

void g(void *p){
    /*...*/
}

void f(struct node *head, const int ok){
    struct node *p=head;

    while (p){
        /* ...
           code 1 
           ...
         */
        if (ok!=0){
            g(p->value);
        }
        p=p->next;
    }
}

我用gcc编译这段代码。如果我使用-O进行编译,它会优化函数f,如下所示:

void f(struct node *head, const int ok){
    struct node *p=head;

    if (ok!=0){
        while (p){
            /* ...
               code 1 
               ...
             */
            g(p->value);
            p=p->next;
        }
    }
    else{
        while (p){
            /* ...
               code 1 
               ...
             */
            p=p->next;
        }
    }
}

3 个答案:

答案 0 :(得分:16)

这在很大程度上取决于/* code 1 */的大小。如果它非常小,它可能会。但如果它超过几行,它很可能不会。为每个if复制大量代码会对性能产生严重影响。事实上,这可能发生在非常激进的优化中,当然不仅仅是-O。从gcc的手册页(强调我的):

  

-O
  -O1 ......

     

使用-O,编译器会尝试减少代码大小执行时间,而不执行任何需要大量编译时间的优化。

因此减少代码也是优化的一部分。

  

-O2优化甚至更多。 GCC几乎执行所有支持的优化,不涉及空速权衡。与-O相比,此选项增加   编译时间和生成代码的性能。

所以-O2也不会做你想做的事。

  

-O3优化更多。 -O3打开-O2指定的所有优化,并打开-finline-functions-funswitch-loops-fpredictive-commoning,    -fgcse-after-reload-ftree-vectorize-fipa-cp-clone选项。

现在我们必须查看这些选项,看看它们中是否有任何可能符合您的要求:

  

-funswitch-loops
   将具有循环不变条件的分支移出循环,在两个分支上重复循环(根据条件的结果进行修改)。

瞧!使用-O3,您可以获得所需的优化。

答案 1 :(得分:2)

嗯,这取决于很多事情。

因为您正在使用gcc,所以您可以通过调用gcc -o -S fileName.c

来检查它是否对特定程序有效

答案 2 :(得分:2)

在这种情况下,我发现这个网站http://gcc.godbolt.org/非常有用