10

这是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;
        }
    }
}
4

3 回答 3

17

这在很大程度上取决于有多大/* 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您一起获得您想要的优化。

于 2013-06-13T09:38:11.097 回答
2

嗯,这取决于很多事情。

由于您正在使用gcc,因此您始终可以通过调用来检查它是否适用于特定程序gcc -o -S fileName.c

于 2013-06-13T09:41:42.373 回答
2

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

于 2013-06-13T09:51:31.743 回答