关闭。这个问题是opinion-based .它目前不接受答案。
想改善这个问题吗?更新问题,以便可以通过 editing this post 用事实和引文回答问题.
5年前关闭。
Improve this question
我目前正在使用 GCC,但我最近发现了 Clang,我正在考虑切换。但是有一个决定性因素 - 它生成的二进制文件的质量(速度、内存占用、可靠性) - 如果 gcc -O3
可以生成运行速度提高 1% 的二进制文件,或者 Clang 二进制文件占用更多内存或者只是由于编译器错误而失败,这是一个交易破坏者。
Clang 拥有比 GCC 更好的编译速度和更低的编译时内存占用,但我真的对生成的编译软件的基准/比较很感兴趣 - 你能给我指出一些或描述你的经验吗?
最佳答案
以下是我对 GCC 4.7.2 的一些最新发现,尽管范围很窄
和 C++ 的 Clang 3.2。
更新:下面附上 GCC 4.8.1 v clang 3.3 比较。
更新:附加了 GCC 4.8.2 v clang 3.4 比较。
我维护一个 OSS 工具,它是为 Linux 构建的,带有 GCC 和 Clang,
并使用 Microsoft 的 Windows 编译器。工具 coan 是一个预处理器
和 C/C++ 源文件和代码行的分析器:它的
递归下降解析和文件处理的计算配置文件专业。
开发分支(这些结果与之相关)
目前在大约 90 个文件中包含大约 11K LOC。它被编码,
现在,在具有丰富多态性和模板的 C++ 中,但仍然
由于其在 C 中被黑客入侵的不远的过去,它陷入了许多补丁中。
没有明确利用移动语义。它是单线程的。一世
没有投入大量精力去优化它,而“架构”
仍然如此主要的待办事项。
我在 3.2 之前使用 Clang 作为实验编译器
因为,尽管它具有卓越的编译速度和诊断能力,
C++11 标准支持落后于当代 GCC 版本
科恩行使的尊重。在 3.2 中,这个差距已经缩小。
我的 Linux 测试工具大致适用于当前的 coan 开发过程
70K 源文件混合了一个文件解析器测试用例,压力
测试消耗 1000 个文件,场景测试消耗 < 1K 文件。
除了报告测试结果外,线束还会累积和
显示消耗的文件总数和 coan 消耗的运行时间
(它只是将每个 coan 命令行传递给 Linux time
命令和
捕获并累加报告的数字)。时机受宠若惊
事实上,任何需要 0 个可测量时间的测试都将
全部加起来为 0,但此类测试的贡献可以忽略不计。这
计时统计信息显示在 make check
的末尾像这样:
coan_test_timer: info: coan processed 70844 input_files.
coan_test_timer: info: run time in coan: 16.4 secs.
coan_test_timer: info: Average processing time per input file: 0.000231 secs.
我比较了 GCC 4.7.2 和
Clang 3.2,除了编译器之外,所有东西都是平等的。从 Clang 3.2 开始,
我不再需要代码之间的任何预处理器区分
GCC 将编译的文件和 Clang 替代品。我建立了
在每种情况下都使用相同的 C++ 库(GCC)并运行所有比较
连续在同一个终端 session 中。
我的发布版本的默认优化级别是 -O2。我也
在 -O3 成功测试构建。我测试了每个配置 3
次背靠背并平均 3 个结果,如下
结果。数据单元中的数字是平均数
coan 可执行文件用于处理每个
~70K 输入文件(读取、解析和写入输出和诊断)。
| -O2 | -O3 |O2/O3|
----------|-----|-----|-----|
GCC-4.7.2 | 231 | 237 |0.97 |
----------|-----|-----|-----|
Clang-3.2 | 234 | 186 |1.25 |
----------|-----|-----|------
GCC/Clang |0.99 | 1.27|
任何特定的应用程序很可能具有发挥作用的特征
对编译器的优势或劣势不公平。严格的标杆管理
使用不同的应用程序。考虑到这一点,值得注意的是
这些数据的特点是:
两个编译器的进一步有趣比较偶然出现
在这些发现之后不久。 Coan 自由地使用智能指针和
其中之一在文件处理中被大量使用。这个特别
为了
编译器差异化,成为
std::unique_ptr<X>
如果配置的编译器对其使用有足够成熟的支持,因为
那个,否则是
std::shared_ptr<X>
.对 std::unique_ptr
的偏见曾是愚蠢,因为这些指针实际上被转移了,
但是
std::unique_ptr
看起来像更换的钳工选项std::auto_ptr
在 C++11 变体对我来说是新事物的时候。在实验性构建过程中评估 Clang 3.2 的持续需求
为了这个和类似的区别,我无意中建立了
std::shared_ptr<X>
当我打算 build std::unique_ptr<X>
,并惊讶地观察到生成的可执行文件,默认为 -O2
优化,是我见过的最快的,有时达到 184
毫秒。每个输入文件。通过对源代码的这一更改,
相应的结果是这些;
| -O2 | -O3 |O2/O3|
----------|-----|-----|-----|
GCC-4.7.2 | 234 | 234 |1.00 |
----------|-----|-----|-----|
Clang-3.2 | 188 | 187 |1.00 |
----------|-----|-----|------
GCC/Clang |1.24 |1.25 |
这里的注意点是:
改变。
改变。
在智能指针类型更改之前和之后,Clang 能够构建一个
在 -O3 优化时大大更快的 coan 可执行文件,并且它可以
在 -O2 和 -O3 处构建同样更快的可执行文件
指针类型是最好的 -
std::shared_ptr<X>
- 为了工作。我无权评论的一个明显问题是为什么
Clang 应该能够在我的应用程序中找到 25% -O2 的加速
大量使用的智能指针类型从唯一更改为共享,
而GCC对同样的变化无动于衷。我也不知道我是否应该
欢呼或嘘声 Clang 的 -O2 优化包含的发现
对我的智能指针选择的智慧如此敏感。
更新:GCC 4.8.1 v clang 3.3
现在对应的结果是:
| -O2 | -O3 |O2/O3|
----------|-----|-----|-----|
GCC-4.8.1 | 442 | 443 |1.00 |
----------|-----|-----|-----|
Clang-3.3 | 374 | 370 |1.01 |
----------|-----|-----|------
GCC/Clang |1.18 |1.20 |
现在处理所有四个可执行文件的平均时间比以前长得多
1 文件不反射(reflect)最新编译器的性能。这是由于
事实上,测试应用程序的后期开发分支已经承担了很多
同时解析复杂性并以速度为代价。只有比率是
重要的。
现在的注意点并不引人注目:
将这些结果与 GCC 4.7.2 和 clang 3.2 的结果进行比较,可以发现
GCC 在每个优化级别都收回了大约四分之一的 clang 领先优势。但
由于测试应用程序在此期间已经大量开发,因此无法
自信地将此归因于 GCC 代码生成的追赶。
(这一次,我注意到了从中获取时间的应用程序快照
并且可以再次使用它。)
更新:GCC 4.8.2 v clang 3.4
我完成了 GCC 4.8.1 v Clang 3.3 的更新,说我会
坚持使用相同的 coan snaphot 以获得进一步的更新。但我决定
而是在该快照(修订版 301)和最新开发上进行测试
我的快照通过了它的测试套件(修订版 619)。这给出了结果
有点经度,我还有另一个动机:
我最初的帖子指出我没有努力优化 coan
速度。这仍然是 rev 的情况。 301.不过,我建好之后
每次我运行测试套件时,将计时装置放入 coan 测试工具中
最新变化对性能的影响让我眼前一亮。我看见了
它通常出人意料地大,而且趋势比
我觉得功能上的进步是值得的。
由 rev。 308 测试套件中每个输入文件的平均处理时间
自从第一次在这里发帖以来,已经翻了一番多。那时我做了一个
彻底改变我 10 年不关心性能的政策。在密集的
高达 619 性能的大量修订始终是一个考虑因素和一个
他们中的很多人纯粹是为了从根本上重写关键的承载者
更快的行(尽管没有使用任何非标准编译器功能来这样做)。看到每个编译器对此的 react 会很有趣
掉头,
这是最新的两个编译器版本 301 的现在熟悉的时序矩阵:
coan - rev.301 结果
| -O2 | -O3 |O2/O3|
----------|-----|-----|-----|
GCC-4.8.2 | 428 | 428 |1.00 |
----------|-----|-----|-----|
Clang-3.4 | 390 | 365 |1.07 |
----------|-----|-----|------
GCC/Clang | 1.1 | 1.17|
这里的故事与 GCC-4.8.1 和 Clang-3.3 相比仅略有改变。 GCC 的显示
好一点。 Clang 的差一点。噪音可以很好地解释这一点。
Clang 仍然领先
-O2
和 -O3
在大多数情况下无关紧要的利润率应用程序,但对相当多的人来说很重要。
这是 rev 的矩阵。 619.
coan - rev.619 结果
| -O2 | -O3 |O2/O3|
----------|-----|-----|-----|
GCC-4.8.2 | 210 | 208 |1.01 |
----------|-----|-----|-----|
Clang-3.4 | 252 | 250 |1.01 |
----------|-----|-----|------
GCC/Clang |0.83 | 0.83|
将 301 和 619 数字并列,有几点可以说明。
我的努力。但是:
-O2
优化 Clang 的 619 构建比其 301 构建快 46%:在 -O3
叮当的提高了 31%。很好,但在每个优化级别 GCC 的 619 构建是
比 301 快两倍多。
GCC 级别现在比 Clang 高 17%。
-O3
优化在 619 版本中消失了。编译器都没有从
-O3
中获得有意义的 yield . 我对这种命运的逆转感到非常惊讶,我怀疑我
可能不小心对 clang 3.4 本身进行了缓慢的构建(因为我构建了
它来自源头)。所以我用我发行版的股票 Clang 3.3 重新运行了 619 测试。这
结果实际上与 3.4 相同。
因此,关于对掉头的 react :就这里的数字而言,Clang 做了很多
比 GCC 更好地从我的 C++ 代码中挤出速度
帮助。当我全神贯注于帮助时,GCC 比 Clang 做得好得多。
我不会将这种观察提升为原则,但我认为
“哪个编译器生成更好的二进制文件?”的教训是个问题
也就是说,即使您指定了与答案相关的测试套件,
对二进制文件进行计时仍然不是一个明确的问题。
你更好的二进制文件是最快的二进制文件,还是最好的二进制文件?
补偿廉价制作的代码?或者最好的补偿昂贵的
精心制作的代码优先考虑可维护性和重用性而不是速度?这取决于
你产生二进制的动机的性质和相对权重,以及
您这样做的约束条件。
无论如何,如果您非常关心构建“最好的”二进制文件,那么您
最好继续检查编译器的连续迭代如何交付给您
在代码的连续迭代中“最好”的想法。
关于optimization - Clang vs GCC - 哪个产生更快的二进制文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3187414/