Подтвердить что ты не робот

Malloc в Windows 10 работает медленнее, чем Windows 7

Я переношу свое приложение из Windows 7 в Windows 10.
Все функции были обработаны без каких-либо изменений, но время выполнения было медленнее, чем окна 7.
Кажется, строительство объекта/разрушение было медленным. Затем я создал простой контрольную программу, касающуюся malloc() и бесплатной(), например, ниже.

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);
}

Я запускал эту программу как в Windows 7, так и в Windows 10 на одном ПК. Я измерил производительность malloc() и free(), когда размер данных равен 1, 100, 1000, 10000, 100000, 1000000, 10000000 и 100000000 байт.
Во всех вышеперечисленных случаях окна 10 медленнее, чем окна 7.
В частности, окна 10 медленнее, чем десятикратные окна 7 при размере данных 10000000 и 100000000.

Когда размер данных составляет 10000000 байт

  • Windows 7: 0.391392 мсек
  • Windows 10: 4.254411 мс

Когда размер данных составляет 100000000 байт

  • Windows 7: 0.602178 мсек
  • Windows 10: 38.713946 мсек

Есть ли у вас предложения по его улучшению в Windows 10?

Я экспериментировал со следующими словами в Windows 10, но производительность не была улучшена, к сожалению.

  • Отключенная суперзапись
  • Отключено Ndu.sys
  • Очистка диска

Вот исходный код. (обновлено 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;
}

Результат в моей среде (построенный VS2010 и Windows 7) В случае 100 МБ:

  • Количество QPC в окнах 7: 11.52 (4.03usec)

  • Количество QPC в окнах 10: 973,28 (341 мсек)

4b9b3361

Ответ 1

Одна вещь, которая может иметь некоторое влияние, состоит в том, что внутренности API QueryPerformanceCounter, очевидно, были изменены с 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 алгоритм синхронизации был значительно улучшен для улучшения разместить большие системы со многими процессорами.


Что еще более важно, ваш код бенчмаркинга сам по себе не работает. QuadPart имеет тип LONGLONG, как и выражение gEnd.QuadPart-gStart.QuadPart. Но вы печатаете это выражение с помощью спецификатора формата %g, который ожидает double. Таким образом, вы вызываете поведение undefined, а вывод, который вы читали, является полной бессмыслицей.

Аналогично, printf("ERROR\n", size); - это еще одна ошибка.


При этом оперативные системы часто не выполняют фактическое распределение кучи до того, как эта область памяти фактически используется. Это означает, что в вашей программе, вероятно, нет фактического распределения.

Чтобы противостоять этому поведению во время бенчмаркинга, вы должны фактически использовать память. Например, вы можете добавить что-то вроде этого, чтобы убедиться, что распределение действительно происходит:

p = malloc(size);
volatile int x = i;
p[0] = x;
free(p);

Ответ 2

Производительность зависит от многих фактов os, ram, cpu и т.д.

Я запускал эту программу как в Windows 7, так и в Windows 10 на одном ПК

cpu вычислить вещи быстрее. Я подозреваю, что ваш процессор и баран не достаточны для  соответствуют окнам 10 и хорошо для окон 7 (более легкое изображение, чем 10)  я предлагаю попробовать другую систему с окнами 10, в которых cpu выборка формы инструкции должна быть достаточно быстрой, а размер бара должен соответствовать процессору, так как вы попадаете в Windows 7 и не забудьте закрыть все приложение, работающее в бэкэнд.