Как использовать все узлы NUMA с openMP в Windows 10 - PullRequest
0 голосов
/ 27 сентября 2018

У меня есть доступ к системе с двумя сокетами, состоящей из двух узлов NUMA, для некоторой обработки данных.

Мой код относительно прост, и я использую openMP для основного параллелизуемого цикла, который выглядит следующим образом ( k - это параметр функции, а буфер - это массив размером в несколько гигабайт n ):

uint64_t m=0;
uint64_t *rk = (uint64_t *) calloc(k, sizeof(uint64_t));
#pragma omp parallel
{
    #pragma omp for reduction(+:m), reduction(+:rk[:k])
    for (uint64_t i=0; i<n-k; i++)
    {
        m += (uint64_t)buffer[i];
        for (uint64_t j=0; j<k; j++)
        {
            rk[j] += (uint64_t)buffer[i]*(uint64_t)buffer[i+j];
        }
    }
    /* Other stuff, serial and parallel */
}

В Linux Mint я могускомпилируйте с gcc без проблем, и все ядра на обоих сокетах будут хорошо использованы.Однако в Windows (mingw-gcc на cygwin) используется только один узел NUMA.Так как мой код не очень чувствителен к задержке памяти, я получаю 2-кратное замедление в Windows.

Я не могу понять, как заставить Windows распределять потоки по обоим узлам.Насколько я понимаю, openMP не поддерживает сходство в Windows (в любом случае реализация cygwin mingw-gcc), но я не знаю, как мне это делать вручную.

Любая помощь очень ценится!

1 Ответ

0 голосов
/ 01 октября 2018

Я нашел причину проблемы.На машине установлено более 64 логических ядер, поэтому для их работы Windows требуется две группы процессоров.По умолчанию каждый узел NUMA помещается в отдельную группу.

Исправление: либо отключение HTT, если у вас менее 64 физических ядер, либо отключение группировки NUMA в BIOS.В последнем случае первые 64 логических ядра будут сгруппированы и будут отображаться как один узел NUMA в Windows, а оставшаяся часть помещается во второй узел.Идеальное решение будет зависеть от вашего конкретного приложения, выиграете ли вы от использования всех ядер или от hyperthreadng ..

[EDIT] Вы также можете управлять потоками вручную.Если вы хотите это сделать, я советую углубиться в Processtopologyapi.h и processthreadsapi.h, в частности в функции GetActiveProcessorCount и SetThreadGroupAffinity.

...