为什么 openmp 不基于手动 NUMA 绑定放置线程?
Why doesn't openmp place threads based on manual NUMA bind?
我正在构建一个 numa 感知处理器,它绑定到给定的插槽并接受 lambda。这是我所做的:
#include <numa.h>
#include <chrono>
#include <cstdlib>
#include <iostream>
#include <thread>
#include <vector>
using namespace std;
unsigned nodes = numa_num_configured_nodes();
unsigned cores = numa_num_configured_cpus();
unsigned cores_per_node = cores / nodes;
int main(int argc, char* argv[]) {
putenv("OMP_PLACES=sockets(1)");
cout << numa_available() << endl; // returns 0
numa_set_interleave_mask(numa_all_nodes_ptr);
int size = 200000000;
for (auto i = 0; i < nodes; ++i) {
auto t = thread([&]() {
// binding to given socket
numa_bind(numa_parse_nodestring(to_string(i).c_str()));
vector<int> v(size, 0);
cout << "node #" << i << ": on CPU " << sched_getcpu() << endl;
#pragma omp parallel for num_threads(cores_per_node) proc_bind(master)
for (auto i = 0; i < 200000000; ++i) {
for (auto j = 0; j < 10; ++j) {
v[i]++;
v[i] *= v[i];
v[i] *= v[i];
}
}
});
t.join();
}
}
但是,所有线程都在套接字 0 上运行。似乎numa_bind
没有将当前线程绑定到给定的套接字。第二个 numa 处理器 -- Numac 1
输出 node #1: on CPU 0
,应该在 CPU 1 上。那么出了什么问题呢?
这完全符合我的预期:
#include <cassert>
#include <iostream>
#include <numa.h>
#include <omp.h>
#include <sched.h>
int main() {
assert (numa_available() != -1);
auto nodes = numa_num_configured_nodes();
auto cores = numa_num_configured_cpus();
auto cores_per_node = cores / nodes;
omp_set_nested(1);
#pragma omp parallel num_threads(nodes)
{
auto outer_thread_id = omp_get_thread_num();
numa_run_on_node(outer_thread_id);
#pragma omp parallel num_threads(cores_per_node)
{
auto inner_thread_id = omp_get_thread_num();
#pragma omp critical
std::cout
<< "Thread " << outer_thread_id << ":" << inner_thread_id
<< " core: " << sched_getcpu() << std::endl;
assert(outer_thread_id == numa_node_of_cpu(sched_getcpu()));
}
}
}
程序首先在我的双插槽服务器上创建 2(外部(线程。然后,它会将它们绑定到不同的套接字(NUMA 节点(。最后,它将每个线程拆分为 20 个(内部(线程,因为每个 CPU 都有 10 个物理内核并启用了超线程。
所有内部线程都与其父线程在同一套接字上运行。即在内核 0-9 和 20-29 上表示外线程 0,在内核 10-19 和 30-39 上表示外线程 1。(在我的情况下,sched_getcpu()
返回了范围 0-39 的虚拟核心数。
请注意,没有 C++11 线程,只有纯 OpenMP。
相关文章:
- 从不同线程使用int64的不同字节安全吗
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 尝试通过OCI例程从Oracle获取blob数据,但出现错误:ORA-01008:并非所有变量都绑定
- 在 openmp 中,omp_get_thread_num是否绑定到物理线程?
- 如何将元素添加到从另一个线程绑定到 XAML 的 IVector
- 为什么 openmp 不基于手动 NUMA 绑定放置线程?
- 为线程构造函数传递引用以将其绑定到函数失败
- 为什么c++中线程构造函数和绑定的函数签名是相同的
- 将线程指针绑定到对象时错误
- boost线程池绑定错误
- 将类方法绑定到线程
- boost::将指针绑定线程到带有参数的函数
- 线程之间以及托管代码和非托管代码之间的绑定
- 具有多个线程的 QML C++ 属性绑定
- 如何通过pthreads将类成员函数与类的对象绑定以创建线程
- c++ /Java绑定:应该在哪一边实现多线程
- 确定性随机数生成器绑定到实例(线程无关)
- Windows 8 APP,用数据绑定改变XAML文本框的文本.游戏循环工作线程导致问题
- 使用OpenMP将线程绑定到特定的CPU内核