Сходство потоков с Windows, MSVC и OpenMP

Я хочу связать потоки в моем коде с каждым физическим ядром. С GCC я успешно сделал это с помощьюsched_setaffinity так что мне больше не нужно устанавливатьexport OMP_PROC_BIND=true, Я хочу сделать то же самое в Windows с MSVC. Windows и Linux используют разные топологии потоков. Linux рассеивает потоки, в то время как Windows использует компактную форму. Другими словами, в Linux с четырьмя ядрами и восемью гиперпотоками мне нужно только связать потоки с первыми четырьмя процессорами. В окнах я установил их на любой другой процессор.

Я успешно сделал это с помощьюSetProcessAffinityMask, Я могу видеть из диспетчера задач Windows, когда я щелкаю правой кнопкой мыши по процессам и нажимаю «Установить сходство», что все остальные процессоры установлены (0, 2, 4, 6 в моей системе с восемью гиперпотоками). Проблема в том, что эффективность моего кода нестабильна при запуске. Иногда это почти постоянно, но в большинстве случаев это большие изменения. Я изменил приоритет на высокий, но это не имеет значения. В Linux эффективность стабильна. Может быть, Windows все еще переносит потоки? Есть ли что-то еще, что мне нужно сделать, чтобы связать темы в Windows?

Вот код, который я использую

#ifdef _WIN32   
HANDLE process;
DWORD_PTR processAffinityMask = 0;
//Windows uses a compact thread topology.  Set mask to every other thread
for(int i=0; i<ncores; i++) processAffinityMask |= 1<<(2*i);        
//processAffinityMask = 0x55;
process = GetCurrentProcess();
SetProcessAffinityMask(process, processAffinityMask);
#else
cpu_set_t  mask;
CPU_ZERO(&mask);
for(int i=0; i<ncores; i++) CPU_SET(i, &mask);      
sched_setaffinity(0, sizeof(mask), &mask);       
#endif

Изменить: вот код, который я использовал сейчас, который кажется стабильным на Linux и Windows

    #ifdef _WIN32   
    HANDLE process;
    DWORD_PTR processAffinityMask;
    //Windows uses a compact thread topology.  Set mask to every other thread
    for(int i=0; i<ncores; i++) processAffinityMask |= 1<<(2*i);
    process = GetCurrentProcess();
    SetProcessAffinityMask(process, processAffinityMask);
    #pragma omp parallel 
    {
        HANDLE thread = GetCurrentThread();
        DWORD_PTR threadAffinityMask = 1<<(2*omp_get_thread_num());
        SetThreadAffinityMask(thread, threadAffinityMask);
    }
    #else
    cpu_set_t  mask;
    CPU_ZERO(&mask);
    for(int i=0; i<ncores; i++) CPU_SET(i, &mask);
    sched_setaffinity(0, sizeof(mask), &mask);
    #pragma omp parallel 
    {
       cpu_set_t  mask;
       CPU_ZERO(&mask);
       CPU_SET(omp_get_thread_num(),&mask);
       pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask); 
    }
    #endif

Ответы на вопрос(1)

Ваш ответ на вопрос