为什么发布版本memset比visual studio 2012中的调试版本慢?

时间:2014-06-05 10:32:02

标签: c++ visual-studio-2012 memset

为什么发布版本memset比visual studio 2012中的调试版本慢? 在视觉sutido 2010中,也是这样的结果。 我的电脑:

英特尔酷睿i7-3770 3.40GHz 8G内存 操作系统:   windows 7 sp1 64bit

这是我的测试代码:

#include <boost/progress.hpp>

int main()
{
    const int Size = 1000*1024*1024;
    char* Data = (char*)malloc(Size);

#ifdef _DEBUG
    printf_s("debug\n");
#else
    printf_s("release\n");
#endif

    boost::progress_timer timer;
    memset(Data, 0, Size);

    return 0;
}

输出:

release
0.27 s

debug
0.06 s

编辑:

if i change code to this, it will get the same result:

#include <boost/progress.hpp>

int main()
{
    const int Size = 1000*1024*1024;
    char* Data = (char*)malloc(Size);
    memset(Data, 1, Size);

#ifdef _DEBUG
    printf_s("debug\n");
#else
    printf_s("release\n");
#endif

    {
        boost::progress_timer timer;
        memset(Data, 0, Size);
    }    

    return 0;
}

所以Hans Passant是对的,非常感谢你。

1 个答案:

答案 0 :(得分:19)

这是一个标准的基准错误,你根本不测量memset()的执行时间。实际上,您可以测量操作系统处理代码生成的25万页错误所需的时间。这高度依赖于正在运行的其他进程以及内核的零页面线程准备了多少页面。

在像Windows这样的需求页面虚拟内存操作系统上,malloc()根本不分配内存。它分配地址空间。只是处理器的数字。在处理器访问地址空间之前,物理内存分配不会发生。此时内核被迫提供物理RAM以允许处理器继续。当处理器发现地址尚未映射到RAM时,由处理器生成的软页面错误触发。

如果你想估计memset()真正需要多长时间,那么你必须调用它两次。第一次调用确保映射RAM。第二次调用时间来测量内存写入所需的时间。对于您正在使用的大内存范围,这是一个固定数字,内存缓存和回写缓冲区无效,因此速度完全取决于内存总线的带宽。您的调试结果表明DDR3的时钟频率为266 MHz,非常常见。

这也消除了在CRT的调试版本中使用调试分配器所产生的偏见。当您尝试访问未初始化的内存时,会使用可能导致崩溃的位模式填充已分配的内存。这隐藏了页面错误开销,因为您没有在测量中包含malloc()的成本。