相关疑难解决方法(0)

以编程方式检测多个物理处理器/核心,或者在Windows,Mac和Linux上是否处于活动状态

我有一个多线程的c ++应用程序,可以在Windows,Mac和一些Linux风格上运行.

简而言之:为了使它以最高效率运行,我必须能够为每个物理处理器/核心实例化一个线程.创建比物理处理器/内核更多的线程会大大降低程序的性能.我已经可以在所有这三个平台上正确检测逻辑处理器/核心的数量.为了能够正确检测物理处理器/内核的数量,我必须检测是否支持超级交叉和活动.

因此,我的问题是,是否有办法检测是否支持超线程并启用?如果是这样,究竟如何.

c++ windows macos assembly hyperthreading

45
推荐指数
9
解决办法
4万
查看次数

使用CAS以原子方式递增两个整数

显然,可以使用比较和交换指令以原子方式递增两个整数.这个谈话声称存在这样的算法,但它没有详细说明它的样子.

在此输入图像描述

如何才能做到这一点?

(注意,一个接一个地递增整数的明显解决方案不是原子的.另外,将多个整数填充到一个机器字中并不算数,因为它会限制可能的范围.)

c concurrency multithreading atomic compare-and-swap

17
推荐指数
1
解决办法
1336
查看次数

由于OpenMP的超线程导致性能不佳:如何将线程绑定到核心

我正在开发大密集矩阵乘法代码.当我对代码进行分析时,它有时会获得我的四个核心系统中大约75%的峰值触发器,而其他时间则大约为36%.在执行代码之间效率不会改变.它要么以75%开始并继续保持效率,要么从36%开始并继续保持这种效率.

我已经将问题追溯到超线程以及我将线程数设置为4而不是默认值8的事实.当我在BIOS中禁用超线程时,我一致地获得大约75%的效率(或者至少我从未看到大幅下降到36%).

在我调用任何并行代码之前omp_set_num_threads(4).我export OMP_NUM_THREADS=4在运行代码之前也尝试过,但它似乎是等效的.

我不想在BIOS中禁用超线程.我想我需要将四个线程绑定到四个核心.我已经测试了一些不同的情况,GOMP_CPU_AFFINITY但到目前为止,我仍然存在效率为36%的问题. 超线程和核心的映射是什么? 例如,线程0和线程1对应于同一个核心和线程2,线程3对应另一个核心吗?

如何在没有线程迁移的情况下将线程绑定到每个核心,这样我就不必在BIOS中禁用超线程? 也许我需要研究使用sched_setaffinity

我当前系统的一些细节:Linux内核3.13,GCC 4.8,Intel Xeon E5-1620(四个物理内核,八个超线程).

编辑:到目前为止,这似乎运作良好

export GOMP_CPU_AFFINITY="0 1 2 3 4 5 6 7"
Run Code Online (Sandbox Code Playgroud)

要么

export GOMP_CPU_AFFINITY="0-7"
Run Code Online (Sandbox Code Playgroud)

编辑:这似乎也运作良好

export OMP_PROC_BIND=true
Run Code Online (Sandbox Code Playgroud)

编辑: 这些选项也很好用(gemm是我的可执行文件的名称)

numactl -C 0,1,2,3 ./gemm
Run Code Online (Sandbox Code Playgroud)

taskset -c 0,1,2,3 ./gemm
Run Code Online (Sandbox Code Playgroud)

gcc scheduler openmp hyperthreading

15
推荐指数
1
解决办法
3897
查看次数

与Windows,MSVC和OpenMP的线程关联

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

我已成功完成此操作SetProcessAffinityMask.当我右键单击进程并单击"Set Affinity"时,我可以从Windows Task Manger中看到每个其他CPU都已设置(我的8个超线程系统上的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
Run Code Online (Sandbox Code Playgroud)

编辑:这是我现在使用的代码,它似乎在Linux和Windows上稳定

    #ifdef _WIN32   
    HANDLE process;
    DWORD_PTR processAffinityMask;
    //Windows uses a compact thread topology.  Set mask to every other …
Run Code Online (Sandbox Code Playgroud)

multithreading openmp affinity visual-c++

6
推荐指数
1
解决办法
4088
查看次数