为啥以下程序在使用 g++ 编译时会慢 15%?

Posted

技术标签:

【中文标题】为啥以下程序在使用 g++ 编译时会慢 15%?【英文标题】:Why is the following program 15% slower when compiled with g++?为什么以下程序在使用 g++ 编译时会慢 15%? 【发布时间】:2009-04-09 02:48:37 【问题描述】:

更新:为我的编译请求提供服务的编译框的实际分辨率不同。在较慢的情况下,我运行的是在 SuSE 9 上编译的代码,但在 SuSE 10 机器上运行。这足以让我放弃它并将苹果与苹果进行比较。使用同一个编译框的结果如下:

g++ 慢了大约 2%

delta real 4 分钟 delta 用户 4 分钟 delta系统5秒

谢谢!

gcc v4.3 vs g++ v4.3 简化为最简单的情况,只使用简单的标志

#include <stdio.h>
#include <stdlib.h>
int main (int argc, char **argv)

    int i=0;
    int j=0;
    int k=0;
    int m=0;
    int n=0;
    for (i=0;i<1000;i++)
        for (j=0;j<6000;j++)
            for (k=0;k<12000;k++)
            
                 m = i+j+k;
                 n=(m+1+1);
            
    return 0;

这是一个已知问题吗? 15% 是非常可复制的。并且全面涵盖真实时间、系统时间和用户时间。我必须等到明天才能发布程序集。

更新:我只尝试了我的一个编译框。我正在使用 SuSE 10。

【问题讨论】:

你检查过组装吗? 如何在没有 char 的情况下在 argv 之前进行编译,更不用说你有错误的指针。 不再工作...从内存中复制了它。 我家里只有 Visual Studio,而且似乎只有 C++ 类型的项目。 那不编译...试试 char **argv 【参考方案1】:

当使用 gcc 和 g++ 编译时,我看到的唯一区别是前 4 行。

gcc:

    .file   "loops.c"
    .def    ___main;    .scl    2;  .type   32; .endef
    .text
.globl _main

g++:

    .file   "loops.c"
    .def    ___main;    .scl    2;  .type   32; .endef
    .text
    .align 2
.globl _main

正如您所见,唯一的区别是在 g++ 中,对齐 (2) 发生在单词边界上。这种微小的差异似乎正在产生显着的性能差异。

这是一个解释结构对齐的页面,虽然它适用于 ARM/NetWinder,但它仍然适用,因为它讨论了对齐如何在现代 CPU 上工作。您将需要专门阅读第 7 节“单词对齐的缺点是什么?” :

http://netwinder.osuosl.org/users/b/brianbr/public_html/alignment.html

这里是 .align 操作的参考:

http://www.nersc.gov/vendor_docs/ibm/asm/align.htm

根据要求进行基准测试:

gcc:

john@awesome:~$ time ./loopsC

real    0m21.212s
user    0m20.957s
sys 0m0.004s

g++:

john@awesome:~$ time ./loopsGPP

real    0m22.111s
user    0m21.817s
sys 0m0.000s

我将最内层的迭代次数减少到 1200。结果并不像我希望的那样普遍,但随后再次在 Windows 上生成了程序集输出,并在 Linux 中完成了计时。也许在 MinGW 的幕后做了一些与 gcc for Linux 对齐方式不同的事情。

【讨论】:

你用的是什么版本的gcc? 4.4.0(截至本文最新) 你能在两个版本的 exe 上运行时间吗?每次我得到的时候,我都有很大的不同。 @John,g++ 正在正确对齐。那么,这不应该更快吗? hmm.. 720 亿次迭代可能需要一点时间【参考方案2】:

为了弄清楚它为什么变慢,您可能需要查看编译器生成的程序集。 g++ 编译器必须做一些不同于 gcc 编译器的事情。

【讨论】:

相同的编译器 - 不同的标志。特别是,g++ 将“compile as C++”标志设置为 GCC。【参考方案3】:

其中一个原因可能是 gcc 可能优化了 m 和 n 的分配,以便它们可以并行运行。

这样就可以了

m = i+j+k;
n = i+j+k+2; 

我不确定这是否能将性能提高 15%。这可能会提高多核 CPU 的性能。最好的方法是比较 2 个编译器的汇编代码。

【讨论】:

也许是优化的对齐方式?【参考方案4】:

哦,那一个有趣的。但是您给我们的代码无法编译。你需要

(int argc, char** argv)

【讨论】:

以上是关于为啥以下程序在使用 g++ 编译时会慢 15%?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 Skylake 上没有 VZEROUPPER 时,这个 SSE 代码会慢 6 倍?

#ifdef 标志来区分 gcc 和 g++ 编译器? [复制]

为啥 UnrealHeaderTool 在构建 RPC 时会失败

为啥在尝试调用采用动态参数的基本构造函数/方法时会出现此编译错误?

为啥要为 c 和 c++ 使用 gcc 和 g++ 编译器驱动程序

为啥我的 Tomcat 服务器在编译 JSP 时会抛出间歇性 404?