Windows SetThreadAffinityMask не имеет никакого эффекта - PullRequest
2 голосов
/ 24 января 2012

Я написал небольшую тестовую программу, в которой я пытаюсь использовать API-интерфейс Windows SetThreadAffinityMask, чтобы привязать поток к одному узлу NUMA. Я получаю битовую маску ЦП узла с помощью вызова API GetNumaNodeProcessorMask, а затем передаю эту битовую маску SetThreadAffinityMask вместе с дескриптором потока, возвращаемым GetCurrentThread. Вот очень упрощенная версия моего кода:

// Inside a function called from a boost::thread
unsigned long long nodeMask = 0;
GetNumaNodeProcessorMask(1, &nodeMask);
HANDLE thread = GetCurrentThread();
SetThreadAffinityMask(thread, nodeMask);
DoWork(); // make-work function

Я, конечно, проверяю, возвращают ли вызовы API 0 в моем коде, и я также распечатал маску узла NUMA, и это именно то, что я ожидал. Я также следовал советам, данным в другом месте, и распечатал маску, возвращенную вторым идентичным вызовом SetThreadAffinityMask, и она соответствует маске узла.

Однако после наблюдения за монитором ресурсов при выполнении функции DoWork работа распределяется по всем ядрам, а не только по тем, с которыми она якобы связана. Есть ли ошибки, которые я мог пропустить при использовании SetThreadAffinityMask? Я использую 64-разрядную версию Windows 7 Professional, и функция DoWork содержит цикл, распараллеленный с OpenMP, который выполняет операции над элементами трех очень больших массивов (которые все еще могут поместиться в узле).

Редактировать: Чтобы расширить ответ Дэвида Шварца, в Windows любые потоки, созданные с помощью OpenMP, НЕ наследуют сходство потоков, которые их породили. Проблема в этом, а не в SetThreadAffinityMask.

1 Ответ

2 голосов
/ 24 января 2012

Вы подтвердили, что конкретный поток, маска сходства которого работала на ядре в другом узле numa?В противном случае, он работает как задумано.Вы устанавливаете маску процессора на один поток, а затем наблюдаете поведение группы потоков.

...