Время доступа к памяти медленное с VirtualAllocExNuma на Windows 7/64 - PullRequest
7 голосов
/ 21 сентября 2010

В нашем приложении мы работаем на двух серверах Xeon с памятью, настроенной как локальная для каждого процессора 12 ГБ, и шиной памяти, соединяющей два Xeon. Из соображений производительности мы хотим контролировать, где мы выделяем большой (> 6 ГБ) блок памяти. Ниже приведен упрощенный код -

DWORD processorNumber = GetCurrentProcessorNumber();
UCHAR   nodeNumber = 255;
GetNumaProcessorNode((UCHAR)processorNumber, &nodeNumber );
// get amount of physical memory available of node.
ULONGLONG availableMemory = MAXLONGLONG;
GetNumaAvailableMemoryNode(nodeNumber, &availableMemory )
// make sure that we don't request too much.  Initial limit will be 75% of available memory
_allocateAmt = qMin(requestedMemory, availableMemory * 3 / 4);
// allocate the cached memory region now.
HANDLE handle = (HANDLE)GetCurrentProcess ();
cacheObject = (char*) VirtualAllocExNuma (handle, 0, _allocateAmt, 
            MEM_COMMIT | MEM_RESERVE ,
            PAGE_READWRITE| PAGE_NOCACHE , nodeNumber);

Код, как есть, работает правильно, используя VS2008 на Win 7 / 64.

В нашем приложении этот блок памяти функционирует как кэш-хранилище для статических объектов (1-2 МБ), которые обычно хранятся на жестком диске. Моя проблема в том, что когда мы переносим данные в область кеша с использованием memcpy, это занимает в 10 раз больше времени, чем если бы мы выделяли память с помощью new char[xxxx]. И никаких других изменений кода.

Мы затрудняемся понять, почему это происходит. Любые предложения относительно того, где искать?

1 Ответ

7 голосов
/ 21 сентября 2010

PAGE_NOCACHE - убийство на перфе, оно отключает кэш процессора. Это было умышленно?

...