【问题标题】:C++ clang array much faster than clang vector and both gcc vector and arrayC++ clang 数组比 clang 向量和 gcc 向量和数组快得多
【发布时间】:2015-05-13 17:46:08
【问题描述】:

下面的代码显示了我的测试用例。我用 clang++ --std=c++11 -O2 和 g++ --std=c++11 -O2 编译。


long long *ary = new long long[100000000]();
for (long long i = 0; i < 100000000; ++i)
    ary[i] = i;

std::vector<long long> vec(100000000, 0);
for (long long i = 0; i < 100000000; ++i)
    vec[i] = i;

对于这两种情况,我只对初始化进行了测试,然后是初始化和 for 循环。结果如下:

海合会:

  • 仅数组初始化:0.182s
  • 数组初始化和for循环:0.250s
  • 仅矢量初始化:0.169s
  • 向量初始化和for循环:0.252

叮当声:

  • 仅数组初始化:0.004s
  • 数组初始化和for循环:0.004s
  • 仅矢量初始化:0.150
  • 向量初始化和for循环:0.240s

gcc 结果与向量与数组一样快的普遍信念相吻合。此外,vector 的 clang 和 gcc 结果非常一致。然而,clang 结果是荒谬的,阵列的执行速度要快得多。有人知道这是为什么吗?

【问题讨论】:

标签: arrays performance c++11 gcc clang


【解决方案1】:

25 倍的加速表明您的代码已经过优化。由于您的代码没有任何可见的内容,因此有资格被删除。您的基准无效。

【讨论】:

  • 你是对的。我添加了 std::cout
  • @JamesLens 也许在未来的某个时间里这还不够。整个数组/向量是一个常数,优化器最终可能会看穿它。我会做不同的事情。将整个向量初始化为外部值,例如从当前时间派生的值。然后,求和并打印总和。由于总和是动态的,即使使用 Gods 编译器也永远无法删除。
【解决方案2】:

这里的区别在于clanggcc 如何优化对new 的调用。以下代码:

long long *ary = new long long[100000000]();
for (long long i = 0; i < 100000000; ++i)
    ary[i] = i;

clang 将在-O2 优化级别对其进行优化(see it live):

xorl    %eax, %eax
retq

gcc 不会see it live

 movl   $800000000, %edi
 call   operator new[](unsigned long)
 leaq   800000000(%rax), %rcx
 movq   %rax, %rdx
.L2:
 movq   $0, (%rdx)
 addq   $8, %rdx
 cmpq   %rcx, %rdx
 jne    .L2
 xorl   %edx, %edx

问题是valid optimization 还是不是?有人可能会争辩说,根据 as-if 规则,这不是一个有效的优化,因为 new can result in observable behavior

这是由提案 N3664: Clarifying Memory Allocation 在 C++14 中进行的有效优化,但 clang 已包含此期间之前的优化,请参阅 this answer

【讨论】:

    猜你喜欢
    • 2012-12-03
    • 2015-07-04
    • 2012-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-13
    • 1970-01-01
    • 2015-06-10
    相关资源
    最近更新 更多