Hilo de afinidad con Windows, MSVC y OpenMP

Quiero vincular los hilos de mi código a cada núcleo físico. Con GCC lo hice con éxitosched_setaffinity así que ya no tengo que configurarexport OMP_PROC_BIND=true. Quiero hacer lo mismo en Windows con MSVC. Windows y Linux utilizando una topología de subproceso diferente. Linux dispersa los hilos mientras que Windows usa una forma compacta. En otras palabras, en Linux con cuatro núcleos y ocho hiperprocesos solo necesito vincular los subprocesos a las primeras cuatro unidades de procesamiento. En Windows, los configuro en cualquier otra unidad de procesamiento.

He hecho esto exitosamente usandoSetProcessAffinityMask. Puedo ver desde el Administrador de tareas de Windows cuando hago clic derecho en los procesos y hago clic en "Establecer afinidad" que cada otra CPU está configurada (0, 2, 4, 6 en mi sistema de ocho hiperprocesos). El problema es que la eficiencia de mi código es inestable cuando ejecuto. A veces es casi constante, pero la mayoría de las veces tiene grandes cambios. Cambié la prioridad a alta pero no hay diferencia. En Linux la eficiencia es estable. ¿Quizás Windows todavía está migrando los hilos? ¿Hay algo más que deba hacer para unir los hilos en Windows?

Aquí está el código que estoy 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

Editar: aquí está el código que usé ahora, que parece ser estable en Linux y 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

Respuestas a la pregunta(1)

Su respuesta a la pregunta