Thread-Affinität zu Windows, MSVC und OpenMP

Ich möchte die Threads in meinem Code an jeden physischen Kern binden. Mit GCC habe ich das erfolgreich gemachtsched_setaffinity so muss ich nicht mehr einstellenexport OMP_PROC_BIND=true. Ich möchte dasselbe in Windows mit MSVC machen. Windows und Linux verwenden eine andere Thread-Topologie. Linux streut die Threads, während Windows eine kompakte Form verwendet. Mit anderen Worten, in Linux mit vier Kernen und acht Hyper-Threads muss ich die Threads nur an die ersten vier Verarbeitungseinheiten binden. In Windows habe ich sie auf jede andere Verarbeitungseinheit gesetzt.

Ich habe dies erfolgreich mit getanSetProcessAffinityMask. Ich kann vom Windows Task Manager aus sehen, wenn ich mit der rechten Maustaste auf die Prozesse klicke und auf "Affinität festlegen" klicke, dass jede andere CPU festgelegt ist (0, 2, 4, 6 auf meinem System mit acht Hyper-Threads). Das Problem ist, dass die Effizienz meines Codes bei der Ausführung instabil ist. Manchmal ist es fast konstant, aber die meiste Zeit hat es große Veränderungen. Ich habe die Priorität in hoch geändert, aber das macht keinen Unterschied. Unter Linux ist die Effizienz stabil. Vielleicht migriert Windows die Threads noch? Muss ich noch etwas tun, um die Threads in Windows zu binden?

Hier ist der Code, den ich benutze

#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

Bearbeiten: hier ist der Code, den ich jetzt verwendet habe und der unter Linux und Windows stabil zu sein scheint

    #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