Visual C ++调试运行时比发布运行时更快?

时间:2014-07-08 09:41:11

标签: c++ visual-c++

我正在尝试做一些性能测试。我发现与Visual C ++(2010)调试运行时链接的代码似乎比与发布运行时链接的运行速度更快。

我可以使用非常简单的代码片段和构建命令行重现问题:

#include <sys/timeb.h>
#include <time.h>
#include <stdio.h>


int main() {
    unsigned int *a= new unsigned int[100000000];
    unsigned int v = 0xaabbccdd;
    timeb start, end;

    ftime(&start);
    clock_t start_cycle = clock();

    for (register int i=0; i<100000000; i++) {
      a[i] += v;
    }   

    clock_t end_cycle = clock();
    ftime(&end);

    printf ("elapsed time: %d ms\n", ((end.time - start.time)*1000 + 
                                       end.millitm - start.millitm));
    printf ("cycles: %d\n", end_cycle - start_cycle);

    delete a;
    return end_cycle - start_cycle;
}

$ cl / O2 / MT test.cc

已用时间:176毫秒

$ cl / O2 / MTd test.cc

已用时间:88毫秒

$ cl / MT test.cc

已用时间:523 ms

$ cl / MTd test.cc

已用时间:480毫秒

当我添加/ Fa选项时,两者都生成相同的汇编代码。

使用MingW32 g ++ -O3构建它给出了类似的发布版本结果:

$ g ++ -O3 test.cc

已用时间:172毫秒

我想知道VC调试运行时如何如此之快。它是否优化/省略了我不知道的东西?

1 个答案:

答案 0 :(得分:3)

unsigned int *a= new unsigned int[100000000];

你正在犯一个传统的基准错误,你启动计时器太晚了。在需求分页的虚拟内存操作系统(如Windows)上,该语句仅分配地址空间。只是处理器的数字,分配中每个4096字节一个。它分配物理内存,只是虚拟内存。

直到稍后,实际开始访问数组元素时才会发生这种情况。这会生成页面错误,即需求分页功能,强制操作系统将地址空间映射到RAM。您的程序将生成97657页错误(100000000 * 4/4096)。

当发生这些页面错误时,调试版本和发布版本之间的区别恰好是。在发布版本中,它们出现在for()循环中,其成本包含在测量中。应该如此。

但是当使用/ MTd或/ MDd构建时,您将使用调试分配器。当您调用未定义的行为并使用未初始化的内存时,哪个initializes allocated heap blocks具有可能使程序崩溃的位模式。初始化会导致相同的页面错误。但是在启动计时器之前发生。所以你的测量是关闭的,它不包括内存映射成本。

您需要在分配之前启动计时器以比较苹果和橙子。