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

Posted

技术标签:

【中文标题】如何在 C++ 程序中通过拓扑考虑在多核 HT 上实现亲和性?【英文标题】:How to implement affinity on multi-core HT with topological considerations in a C++ program? 【发布时间】:2011-10-18 17:54:50 【问题描述】:

我正在开发一些具有可变线程数的 C++ 多核程序,我想知道如何设置适当的(实际上是“最佳”)亲和力。我使用 Boost-threads,所以我可以调用 get_hardware_concurrency() 来了解有多少逻辑内核。到目前为止,我写了一个映射“第 n 个线程到第 n 个逻辑核心”,但这并不是最聪明的事情,因为多插槽处理器和超线程。我的程第 2 个物理上的第 1 个逻辑,...,第 n 个物理上的第 1 个逻辑,第 1 个物理上的第 2 个逻辑等等。

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

尽可能简洁:我如何知道操作系统(Windows 和 Linux)称为第 N 个线程的确切位置(物理内核和包)?

【问题讨论】:

【参考方案1】:

这是一段代码 sn-p,它将为您提供 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),无需任何代码行。

【讨论】:

谢谢,这会很有帮助。但是,要在 C++ 程序中使用此代码,我想我应该从 system() 指令中调用它。我可以避免吗?顺便说一句,它比使用 asm、cpuid 和所有那些汇编的东西要好得多! 我不会用系统调用它。我的建议是,在 shell 脚本中创建一个包装器,首先找到 cpu 拓扑,然后将其作为参数传递给您的程序。【参考方案2】:

对于 Windows:GetLogicalProcessorInformation 和 SetThreadAffinityMask

还有GetCurrentProcessorNumber(),但是当您不将它们固定到特定 CPU 时,操作系统会频繁交换线程,因此这对您自己的目的没有帮助。

【讨论】:

+ 在GetLogicalProcessorInformation 之上的即用型工具:alax.info/blog/1188 显示配置。【参考方案3】:

在linux上,看看man pages for sched_setaffinity

【讨论】:

【参考方案4】:

LIKWID 工具套件可以方便地处理多核环境中的拓扑和亲和性问题。除其他外,它还包含用于确定拓扑、将线程固定到内核以及测量硬件性能指标的工具:

http://code.google.com/p/likwid

只要代码中的线程机制是基于pthreads并且应用程序是动态链接的,likwid-pin就可以在不改变源代码的情况下将线程绑定到资源。

【讨论】:

以上是关于如何在 C++ 程序中通过拓扑考虑在多核 HT 上实现亲和性?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 MSYS2 中通过 CMake 构建 c++ Qt5 应用程序

如何在 C++ 中通过 Rcpp 使用 Boost 库

在 C++ 中通过网格/矩阵找到成本优化路径

如何在 C++ 中通过指针传递字符串?

如何在 C++ 中通过引用返回向量

在 C++ 中通过 csv 文件的更快方法