Windows 10中的malloc比Windows 7慢

ple*_*s92 20 c performance windows-10

我正在将我的应用程序从Windows 7迁移到Windows 10.
所有功能都没有任何更改,但执行时间比Windows 7
慢.似乎对象构造/破坏很慢.然后我创建了关于malloc()和free()的简单基准程序,如下所示.

for (int i = 0; i < 100; i++)
{
  QueryPerformanceCounter(&gStart);
  p = malloc(size);
  free(p);
  QueryPerformanceCounter(&gEnd);
  printf("%d, %g\n", i, gEnd.QuadPart-gStart.QuadPart);
  if (p == NULL)
    printf("ERROR\n", size);
}
Run Code Online (Sandbox Code Playgroud)

我在同一台PC上的Windows 7和Windows 10中运行了这个程序.当数据大小为1,100,1000,10000,100000,1000000,10000000和100000000字节时,我测量了malloc()和free()性能.
在所有上述情况中,窗口10比窗口7慢.
特别是,当数据大小为10000000和100000000时,窗口10的速度超过十倍窗口7.

当数据大小为10000000字节时

  • Windows 7:0.391392毫秒
  • Windows 10:4.254411毫秒

当数据大小为100000000字节时

  • Windows 7:0.602178毫秒
  • Windows 10:38.713946毫秒

你有什么建议在Windows 10上改进吗?

我已经在Windows 10中尝试了以下内容,但遗憾的是性能没有得到改善.

  • 禁用超级抓取
  • 已禁用Ndu.sys
  • 磁盘清理

这是源代码.(2月15日更新)

#include "stdafx.h"

#define START_TIME  QueryPerformanceCounter(&gStart);
#define END_TIME    QueryPerformanceCounter(&gEnd);

#define PRT_FMT(fmt, ...)   printf(fmt, __VA_ARGS__); 
#define PRT_TITLE(fmt, ...) printf(fmt, __VA_ARGS__); gTotal.QuadPart = 0;
#define PRT_RESULT  printf(",%d", gEnd.QuadPart-gStart.QuadPart); gTotal.QuadPart+=(gEnd.QuadPart-gStart.QuadPart);
#define PRT_END printf("\n");
//#define PRT_END       printf(",total,%d,%d\n", gTotal.QuadPart, gTotal.QuadPart*1000000/gFreq.QuadPart);


LARGE_INTEGER gStart;
LARGE_INTEGER gEnd;
LARGE_INTEGER gTotal;
LARGE_INTEGER gFreq;

void
t_Empty()
{
    PRT_TITLE("02_Empty");
    START_TIME
    END_TIME; PRT_RESULT
    PRT_END
}
void
t_Sleep1234()
{
    PRT_TITLE("01_Sleep1234");
    START_TIME
        Sleep(1234);
    END_TIME; PRT_RESULT
    PRT_END
}

void*
t_Malloc_Free(size_t size)
{
    void* pVoid;

    PRT_TITLE("Malloc_Free_%d", size);
    for(int i=0; i<100; i++)
    {
        START_TIME
        pVoid = malloc(size);
        free(pVoid);
        END_TIME; PRT_RESULT
        if(pVoid == NULL)
        {
            PRT_FMT("ERROR size(%d)", size);
        }

    }
    PRT_END

    return pVoid;
}

int _tmain(int argc, _TCHAR* argv[])
{
    int i;
    QueryPerformanceFrequency(&gFreq);
    PRT_FMT("00_QueryPerformanceFrequency, %lld\n", gFreq.QuadPart);

    t_Empty();
    t_Sleep1234();

    for(i=0; i<10; i++)
    {
        t_Malloc_Free(1);
        t_Malloc_Free(100);
        t_Malloc_Free(1000);        //1KB
        t_Malloc_Free(10000);
        t_Malloc_Free(100000);
        t_Malloc_Free(1000000);     //1MB
        t_Malloc_Free(10000000);    //10MB
        t_Malloc_Free(100000000);   //100MB
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

结果在我的环境中(由VS2010和Windows 7构建)在100MB的情况下:

  • Windows 7中的QPC计数:11.52(4.03usec)

  • Windows 10中的QPC计数:973.28(341毫秒)

Lun*_*din 6

可能产生一些影响的一件事是QueryPerformanceCounterAPI 的内部 显然已从Windows 7更改为Windows 8. https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs. 85)的.aspx

Windows 8,Windows 8.1,Windows Server 2012和Windows Server 2012 R2使用TSC作为性能计数器的基础.TSC同步算法得到了显着改进,以更好地适应具有许多处理器的大型系统.


更重要的是,您的基准测试代码本身已被破坏.QuadPartLONGLONG表达的类型gEnd.QuadPart-gStart.QuadPart.但是您使用%g期望a 的格式说明符打印此表达式double.因此,您调用未定义的行为,您正在阅读的输出完全是废话.

同样,printf("ERROR\n", size);是另一个错误.


话虽这么说,操作系统通常不会在实际使用该存储区之前进行实际的堆分配.这意味着您的程序中可能没有实际分配.

要在基准测试期间抵消此行为,您必须实际使用内存.例如,您可以添加类似的内容以确保实际发生分配:

p = malloc(size);
volatile int x = i;
p[0] = x;
free(p);
Run Code Online (Sandbox Code Playgroud)

  • 如果size大于一个字节,那么memset整个缓冲区可能是明智之举,所以整个事情都会被带入内存. (2认同)

leu*_*age -7

性能取决于许多因素,如操作系统、内存、CPU 等。

我在同一台电脑上的 Windows 7 和 Windows 10 中运行了这个程序

cpu 计算速度更快。我怀疑你的 cpu 和 ram 不足以匹配 windows 10,并且适合 windows 7(比 10 更亮的图像)我建议尝试使用 windows 10 的其他系统,其中 cpu 从 ram 获取指令应该足够快RAM 大小应与您使用 Windows 7 时的 CPU 相匹配,并确保关闭后端运行的所有应用程序。