为啥以下程序在使用 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 时会失败
为啥在尝试调用采用动态参数的基本构造函数/方法时会出现此编译错误?