Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 与Windows、MSVC和OpenMP的线程关联_Multithreading_Visual C++_Openmp_Affinity - Fatal编程技术网

Multithreading 与Windows、MSVC和OpenMP的线程关联

Multithreading 与Windows、MSVC和OpenMP的线程关联,multithreading,visual-c++,openmp,affinity,Multithreading,Visual C++,Openmp,Affinity,我想将代码中的线程绑定到每个物理核心。 有了GCC,我已经使用sched_setaffinity成功地完成了这项工作,因此我不再需要设置export-OMP\u-PROC\u-BIND=true。我想用MSVC在Windows中做同样的事情。Windows和Linux使用不同的线程拓扑。Linux分散线程,而windows使用紧凑形式。换句话说,在具有四个内核和八个超线程的Linux中,我只需要将线程绑定到前四个处理单元。在windows中,我将它们设置为每隔一个处理单元 我已经使用SetPro

我想将代码中的线程绑定到每个物理核心。 有了GCC,我已经使用
sched_setaffinity
成功地完成了这项工作,因此我不再需要设置
export-OMP\u-PROC\u-BIND=true
。我想用MSVC在Windows中做同样的事情。Windows和Linux使用不同的线程拓扑。Linux分散线程,而windows使用紧凑形式。换句话说,在具有四个内核和八个超线程的Linux中,我只需要将线程绑定到前四个处理单元。在windows中,我将它们设置为每隔一个处理单元

我已经使用
SetProcessAffinityMask
成功地完成了这项工作。当我右键单击进程并单击“设置关联性”时,我可以从Windows任务管理器中看到每隔一个CPU都已设置(在我的八超线程系统上为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
\ifdef\u WIN32
处理过程;
DWORD_PTR processAffinityMask=0;
//Windows使用紧凑的线程拓扑。将掩码设置为每隔一个线程

对于(int i=0;i您应该使用
SetThreadAffinityMask
函数(请参阅)。您正在设置进程的掩码

您可以使用以下代码在OpenMP中获取
线程ID

int tid = omp_get_thread_num();
但是,上面的代码提供了OpenMP的内部
线程ID
,而不是系统
线程ID
。本文详细介绍了该主题:

如果需要显式使用这些trhead,请使用显式
关联类型
,如本英特尔文档中所述:


在这两种平台上,您的代码为每个线程设置进程关联掩码而不是关联掩码,因此调度程序仍然可以在进程关联掩码允许的CPU之间自由移动线程。@hristoilev,我理解您的意思。您知道如何获取OpenMP创建的每个线程的线程句柄吗?在并行区域用于获取当前线程的句柄,并根据
omp\u get\u thread\u num()的结果为其分配一个具有单个位集的关联掩码
@HristoIliev,你是说在并行区内?我试过了,它会为每个线程返回相同的句柄。我会继续尝试…我的意思是从并行区内调用它,以便所有OpenMP线程都进行调用。在这种情况下,它不应该返回相同的线程句柄,除非你分配给共享变量。你有一些e吗示例代码?我是指为每个线程设置掩码的代码?可能有办法获取与进程关联的线程并在其上循环。Microsoft的OpenMP实现使用系统管理的线程池。枚举和绑定所有进程线程会影响不属于线程池的一些线程(例如,管理器线程,可能隐藏的窗口消息循环线程等)。我会在并行区域内执行绑定。顺便说一句,有很多方法可以创建导致问题的不良关联掩码。如果您要手动设置线程关联,您应该看一看示例。
int tid = omp_get_thread_num();