与Windows,MSVC和OpenMP的线程关联 [英] Thread affinity with Windows, MSVC, and OpenMP

查看:143
本文介绍了与Windows,MSVC和OpenMP的线程关联的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将代码中的线程绑定到每个物理核心. 使用GCC,我已经使用sched_setaffinity成功完成了此操作,因此不再需要设置export OMP_PROC_BIND=true.我想在Windows中使用MSVC做同样的事情. Windows和Linux使用不同的线程拓扑. Linux分散线程,而Windows使用紧凑形式.换句话说,在具有四个内核和八个超线程的Linux中,我只需要将线程绑定到前四个处理单元即可.在Windows中,我将它们设置为每个其他处理单元.

I want to bind the threads in my code to each physical core. With GCC I have successfully done this using sched_setaffinity so I no longer have to set export OMP_PROC_BIND=true. I want to do the same thing in Windows with MSVC. Windows and Linux using a different thread topology. Linux scatters the threads while windows uses a compact form. In other words in Linux with four cores and eight hyper-threads I only need to bind the threads to the first four processing units. In windows I set them to to every other processing unit.

我已经使用SetProcessAffinityMask成功完成了此操作.当我右键单击进程并单击设置关联性"时,可以从Windows Task Manger中看到其他所有CPU都已设置(在我的8个超线程系统上为0、2、4、6).问题是我运行时代码的效率不稳定.有时它几乎是恒定的,但是在大多数情况下它都有很大的变化.我将优先级更改为高,但没有区别.在Linux中,效率是稳定的.也许Windows仍在迁移线程?我还需要做其他事情来绑定Windows中的线程吗?

I have successfully done this using SetProcessAffinityMask. I can see from Windows Task Manger when I right click on the processes and click "Set Affinity" that every other CPU is set (0, 2, 4, 6 on my eight hyper thread system). The problem is that the efficiency of my code is unstable when I run. Sometimes it's nearly constant but most of the time it has big changes. I changed the priority to high but it makes no difference. In Linux the efficiency is stable. Maybe Windows is still migrating the threads? Is there something else I need to do to bind the threads in 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上是稳定的

here is the code I used now which seems to be stable on Linux and 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

推荐答案

您应该使用SetThreadAffinityMask函数(请参阅

You should use the SetThreadAffinityMask function (see MSDN reference). You are setting the process's mask.

您可以使用以下代码在OpenMP中获得thread ID:

You can obtain a thread ID in OpenMP with this code:

int tid = omp_get_thread_num();

但是,上面的代码提供了OpenMP的内部thread ID,而不提供系统thread ID.本文介绍了有关该主题的更多信息:

However the code above provides OpenMP's internal thread ID, and not the system thread ID. This article explains more on the subject:

http://msdn.microsoft.com/en-us/magazine/cc163717.aspx

如果您需要显式使用这些trhead,请按照此英特尔文档中的说明使用显式 affinity type:

if you need to explicitly work with those trheads - use the explicit affinity type as explained in this Intel documentation:

https://software.intel.com/sites/products/documentation/studio/composer/zh-CN/2011Update/compiler_c/optaps/common/optaps_openmp_thread_affinity.htm

这篇关于与Windows,MSVC和OpenMP的线程关联的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆