我正在开发一些具有可变数量线程的C ++多核程序,我想知道如何设置一个合适的(实际上是“最好的”)亲和力。我使用Boost-threads,所以我可以调用get_hardware_concurrency()来了解有多少逻辑内核。到目前为止,我写了一个映射“第n个线程到第n个逻辑核心”,但由于多插槽处理器和超线程,它并不是最聪明的事情。我的程序总是像SIMD一样,所以线程之间没有任何共享,如果是HT计算机,我想以我能想象的最聪明的方式将线程绑定到逻辑核心:第一个物理上的第一个逻辑核心,第2个物理上的第1个逻辑,...,第1个物理上的第1个逻辑,第1个物理上的第2个逻辑,依此类推。
我发现了很多内容,讨论了如何发现HT是否启用(CPUID)以及如何确定逻辑和物理内核PER包。我知道我必须处理一些汇编代码,它并没有吓到我,但我真的找不到如何知道有关逻辑内核,物理内核和软件包的完整信息以及操作系统如何处理所有这些信息。
我能够最简洁:我怎么知道OS(Windows和Linux)引用的线程的确切位置(物理核心和包)为第N个?
答案 0 :(得分: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
如果我在启用了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
在这里你可以看到cpu 0和4在同一个核心上,即核心0上的HT线程。
将此与sched_setaffinity或pthread_setaffinity_np(3)结合使用,可以将进程映射到一组CPU。您也可以使用taskset(1)而不使用任何代码行。
答案 1 :(得分:3)
对于Windows:GetLogicalProcessorInformation和SetThreadAffinityMask
还有GetCurrentProcessorNumber()
,但是当你没有将它们固定到特定的CPU时,操作系统经常交换线程,所以这对你自己的目的没有帮助。
答案 2 :(得分:1)
在linux上,请查看man pages for sched_setaffinity
答案 3 :(得分:1)
http://code.google.com/p/likwid
只要代码中的线程机制基于pthread并且应用程序是动态链接的,likwid-pin就可以将线程绑定到资源而无需更改源代码。