如何在C++程序中以拓扑考虑实现多核HT的亲和性?

bia*_*986 1 c++ multicore affinity hyperthreading

我正在开发一些具有可变数量线程的C++多核程序,我想知道如何设置一个合适的(实际上是"最好的")亲和力.我使用Boost-threads,所以我可以调用get_hardware_concurrency()来了解有多少逻辑内核.到目前为止,我写了一个映射"第n个线程到第n个逻辑核心",但由于多插槽处理器和超线程,它并不是最聪明的事情.我的程序总是像SIMD一样,所以线程之间没有任何共享,如果是HT计算机,我想以我能想象的最聪明的方式将线程绑定到逻辑核心:第一个物理上的第一个逻辑核心,第2个物理上的第1个逻辑,...,第1个物理上的第1个逻辑,第1个物理上的第2个逻辑,依此类推.

我发现了很多内容,讨论了如何发现HT是否启用(CPUID)以及如何确定逻辑和物理内核PER包.我知道我必须处理一些汇编代码,它并没有吓到我,但我真的找不到如何知道有关逻辑内核,物理内核和软件包的完整信息以及操作系统如何处理所有这些信息.

作为最简洁的我可以:我怎么知道OS(Windows和Linux)引用的线程的确切位置(物理核心和包)为N-th?

fsa*_*ues 5

这是一个代码片段,它将为您提供Linux上的CPU拓扑.

#!/bin/bash
function filter {
  cat /proc/cpuinfo | grep -E "$1.*: [0-9]*" | sed -e 's/^.*: //g'
}

CPU_ID=`filter processor`
SOCKET_ID=(`filter 'physical id'`)
CORE_ID=(`filter 'core id'`)

for cpu_id in $CPU_ID; do
    echo "cpu $cpu_id: socket${SOCKET_ID[$cpu_id]}_core${CORE_ID[$cpu_id]}"
done
Run Code Online (Sandbox Code Playgroud)

如果我在启用HT的核心i7上运行它,我会得到以下输出:

cpu 0: socket0_core0
cpu 1: socket0_core1
cpu 2: socket0_core2
cpu 3: socket0_core3
cpu 4: socket0_core0
cpu 5: socket0_core1
cpu 6: socket0_core2
cpu 7: socket0_core3
Run Code Online (Sandbox Code Playgroud)

在这里你可以看到cpu 0和4在同一个核心上,即核心0上的HT线程.

将此与sched_setaffinity或pthread_setaffinity_np(3)结合使用将允许您将进程映射到一组CPU.您也可以在没有代码行的情况下使用任务集(1).