首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >郎朗与gcc的异同

郎朗与gcc的异同
EN

Stack Overflow用户
提问于 2016-04-11 15:22:36
回答 2查看 19.2K关注 0票数 22

我在不同的项目中使用了这两个编译器。

它们在代码处理和输出生成方面有何不同?例如,gccclang都有用于优化的-O2选项。它们在优化代码方面的操作方式(高层)是相同的吗?我做了一个小测试,例如,如果我有以下代码:

代码语言:javascript
运行
复制
int foo(int num) {
    if(num % 2 == 1)
        return num * num;
    else
        return num * num +1;  
}

以下是clang和-O2的输出程序集:

代码语言:javascript
运行
复制
----gcc 5.3.0-----                              ----clang 3.8.0----
foo(int):                                       foo(int):
        movl    %edi, %edx                              movl    %edi, %eax
        shrl    $31, %edx                               shrl    $31, %eax
        leal    (%rdi,%rdx), %eax                       addl    %edi, %eax
        andl    $1, %eax                                andl    $-2, %eax
        subl    %edx, %eax                              movl    %edi, %ecx
        cmpl    $1, %eax                                subl    %eax, %ecx
        je      .L5                                     imull   %edi, %edi
        imull   %edi, %edi                              cmpl    $1, %ecx
        leal    1(%rdi), %eax                           setne   %al
        ret                                             movzbl  %al, %eax
.L5:                                                    addl    %edi, %eax
        movl    %edi, %eax                              retq
        imull   %edi, %eax
        ret

可以看出,输出具有不同的指令。所以我的问题是,在不同的项目中,他们中的一个是否比另一个更有优势?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-04-11 15:51:49

是。也不是。

这就像是问奥迪汽车是否比梅赛德斯汽车更有优势。和它们一样,这两个编译器是两个不同的项目,目的是做同样的事情。在某些情况下,gcc将发出更好的代码,而在其他情况下,它将是clang

当你需要知道的时候,你必须用两者来编译你的代码,然后测量它。

有一个参数是here和一些不太相关的here

票数 25
EN

Stack Overflow用户

发布于 2016-04-11 15:50:11

在本例中,Clang输出更好一些,因为它不进行分支;相反,它加载num % 2 == 1的值以al由gcc生成的代码使用跳转。如果期望num是偶数/奇数,概率为50%,并且没有重复模式,则由GCC生成的代码将是susceptible to branch prediction failure

但是,您也可以通过执行以下操作来使代码在GCC上运行良好

代码语言:javascript
运行
复制
int foo(int num) {
    return num * num + (num % 2 != 1);
}

更重要的是,看起来你的算法实际上是为无符号数定义的,你应该使用unsigned int (它们对于负数是不同的)-实际上你通过使用unsigned int作为参数可以获得很大的加速,因为现在GCC/Clang可以将num % 2优化为num & 1

代码语言:javascript
运行
复制
unsigned int foo(unsigned int num) {
    return num * num + (num % 2 != 1);
}

gcc -O2生成的结果代码

代码语言:javascript
运行
复制
movl    %edi, %edx
imull   %edi, %edi
andl    $1, %edx
xorl    $1, %edx
leal    (%rdi,%rdx), %eax
ret

比由这两个编译器生成的原始函数的代码要好得多。因此,编译器并不像知道自己在做什么的程序员那么重要。

票数 17
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36542284

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档