Afinidade de threads com Windows, MSVC e OpenMP

Quero vincular os threads no meu código a cada núcleo físico. Com o GCC, fiz isso com sucesso usandosched_setaffinity então não preciso mais definirexport OMP_PROC_BIND=true. Eu quero fazer a mesma coisa no Windows com MSVC. Windows e Linux usando uma topologia de encadeamento diferente. O Linux dispersa os threads enquanto o Windows usa um formato compacto. Em outras palavras, no Linux com quatro núcleos e oito hiper-threads, eu só preciso vincular os threads às quatro primeiras unidades de processamento. No Windows, eu os defino em todas as outras unidades de processamento.

Eu fiz isso com sucesso usandoSetProcessAffinityMask. Consigo ver no Gerenciador de tarefas do Windows quando clico com o botão direito do mouse nos processos e clico em "Definir afinidade" que todas as outras CPUs estão definidas (0, 2, 4, 6 no meu sistema de oito hiper threads). O problema é que a eficiência do meu código é instável quando executo. Às vezes é quase constante, mas na maioria das vezes tem grandes mudanças. Mudei a prioridade para alta, mas não faz diferença. No Linux, a eficiência é estável. Talvez o Windows ainda esteja migrando os threads? Há algo mais que preciso fazer para vincular os threads no Windows?

Aqui está o código que estou usando

#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

Edit: aqui está o código que usei agora que parece estável no Linux e 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

questionAnswers(1)

yourAnswerToTheQuestion