c – 为什么这个无操作循环没有被优化掉?

下面的代码一个被解释为浮点数的零数组复制到另一个数组,并打印此操作的时间.正如我已经看到许多情况,其中无操作循环只是被编译器(包括 gcc)优化掉了,我在等待更改我的复制数组程序的某些时候,它将停止进行复制.
#include <iostream>
#include <cstring>
#include <sys/time.h>

static inline long double currentTime()
{
    timespec ts;
    clock_gettime(CLOCK_MONOTONIC,&ts);
    return ts.tv_sec+(long double)(ts.tv_nsec)*1e-9;
}

int main()
{
    size_t W=20000,H=10000;

    float* data1=new float[W*H];
    float* data2=new float[W*H];
    memset(data1,W*H*sizeof(float));
    memset(data2,W*H*sizeof(float));

    long double time1=currentTime();
    for(int q=0;q<16;++q) // take more time
        for(int k=0;k<W*H;++k)
            data2[k]=data1[k];
    long double time2=currentTime();

    std::cout << (time2-time1)*1e+3 << " ms\n";

    delete[] data1;
    delete[] data2;
}

我用g 4.8.1命令g main.cpp -o test -std = c 0x -O3 -lrt编译了这个.这个程序为我打印6952.17毫秒. (我不得不设置ulimit -s 2000000,以免崩溃.)

我还尝试使用新的自动VLA更改数组的创建,删除memset,但这不会改变g行为(除了更改时间几次).

似乎编译器可以证明这段代码不会做任何合理的事情,那么为什么不优化循环呢?

解决方法

无论如何,这不是不可能的(铿锵3.3版):
clang++ main.cpp -o test -std=c++0x -O3 -lrt

该程序为我打印0.000367毫秒……并查看汇编语言:

...
callq   clock_gettime
movq    56(%rsp),%r14
movq    64(%rsp),%rbx
leaq    56(%rsp),%rsi
movl    $1,%edi
callq   clock_gettime
...

而对于g:

...
call    clock_gettime
fildq   32(%rsp)
movl    $16,%eax
fildq   40(%rsp)
fmull   .LC0(%rip)
faddp   %st,%st(1)
.p2align 4,10
.p2align 3
.L2:
 movl    $1,%ecx
 xorl    %edx,%edx
 jmp     .L5
 .p2align 4,10
 .p2align 3
 .L3:
 movq    %rcx,%rdx
 movq    %rsi,%rcx
 .L5:
 leaq    1(%rcx),%rsi
 movss   0(%rbp,%rdx,4),%xmm0
 movss   %xmm0,(%rbx,4)
 cmpq    $200000001,%rsi
 jne     .L3
 subl    $1,%eax
 jne     .L2
 fstpt   16(%rsp)
 leaq    32(%rsp),%rsi
 movl    $1,%edi
 call    clock_gettime
 ...

编辑(g v4.8.2 / clang v3.3)

消息代码 – 原始版本(1)

...
size_t W=20000,H=10000;

float* data1=new float[W*H];
float* data2=new float[W*H];
...

来源代码修改版(2)

...
const size_t W=20000;
const size_t H=10000;

float data1[W*H];
float data2[W*H];
...

现在未优化的情况是(1)g

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...