C++ NUMA:如何检查RAM的哪个部分是C++;阵列是否已分配?
我有一个服务器,有2个CPU和64GB的RAM,每个CPU 32GB 我知道每个CPU都有自己的RAM部分,让我们称它们为RAM1和RAM2。我想让我的程序知道它在哪个RAM(RAM1或RAM2)上分配数据 我尝试检查指针值:C++ NUMA:如何检查RAM的哪个部分是C++;阵列是否已分配?,c++,multithreading,virtual-memory,numa,C++,Multithreading,Virtual Memory,Numa,我有一个服务器,有2个CPU和64GB的RAM,每个CPU 32GB 我知道每个CPU都有自己的RAM部分,让我们称它们为RAM1和RAM2。我想让我的程序知道它在哪个RAM(RAM1或RAM2)上分配数据 我尝试检查指针值: // put the thread at i-th CPU, using pthread_setaffinity_np TData *a = new TData[N]; ... cout << "CPU = " << i << "
// put the thread at i-th CPU, using pthread_setaffinity_np
TData *a = new TData[N];
...
cout << "CPU = " << i << " adress = " << a << endl;
//使用pthread\u setaffinity\u np将线程放在第i个CPU上
TData*a=新的TData[N];
...
cout内存是通过MMU虚拟化的,因此每个进程都会看到一个大小等于2^64的内存空间。在这个过程中,地址是虚拟的,所以它们是没有意义的。在进程级别,虚拟地址(应用程序可以看到)和物理地址(RAM上)之间没有任何响应
您的应用程序应该查询操作系统,以了解它当前使用的物理地址。您的问题得到了回答。我只想补充一些意见
请注意,调用new[]
实际上并不分配物理内存。在现代操作系统上,这只会导致匿名内存映射。匿名映射与文件系统中的文件不对应,而是由交换(如果有)支持。最初,整个区域指向内核中包含所有零的只读页。只有当您实际写入新分配的内存时,才会安装一个新的内存页,它将替换访问地址所在页面范围的零页。这就是为什么我们说零页是映射到进程的虚拟地址空间的写时拷贝(或CoW)。默认策略是尝试在访问内存区域的线程运行的同一NUMA节点上分配新页。这被称为“首次接触”NUMA政策。如果该NUMA节点上没有足够的内存,则会在其他具有足够可用内存的节点上分配页面。小分配也可以在更大的区域内(称为竞技场),由C库内存分配器<代码> MARROCK()/<代码>(C++操作符<代码> NeX[]/COD>调用<代码> MALROCK()/<代码>以进行实际内存分配。在这种情况下,甚至在写入新分配的内存之前,页可能已经存在于物理内存中
Linux有一个坏习惯,就是在交换时不保留内存区域的NUMA关联。也就是说,如果在NUMA节点0上分配了一个页面,然后调出再调回,则无法保证该页面不会被放置在NUMA节点1上。这使得“我的内存分配在哪里”的问题变得有点棘手,因为一个连续的调出后再调入很容易使您在几秒钟前从move\u pages()
获得的结果无效。因此,该问题仅在以下两种特殊情况下才有意义:
- 显式锁定内存区域:可以使用
mlock(2)
系统调用告诉操作系统不要从进程虚拟地址空间交换特定范围李>
- 您的系统没有活动的交换区:这可以防止操作系统将页面从主内存移出或移回主内存
可能的副本的可能副本看起来很相关,可能会解决@klm123的问题。然而,问题是不同的。这个问题是关于在内存分配到哪里之后如何检查,这个问题是关于预先听写内存应该分配到哪里。@perreal,我看到了这个问题并给出了答案。它如何回答我的问题?@klm123,据我从答案中了解,你试图做的已经是默认行为。但是如果你真的想验证一个本地分配,那么很抱歉投票结果不合格。@perreal,是的,我想知道一种验证方法,因为看起来我在内存分配方面有问题。我的CPU随机地全部或部分加载。可能是不同的原因,我想确定。如果给定应用程序的PID(可以通过在C++代码中运行GETPIDE()来实现),应该有一些条目在/PRO/PID/。它可以是/proc/PID/map。我的应用程序在两个cpu上运行。/proc/PID/map
不公开任何NUMA相关信息/proc/PID/numa_maps
是一个公开的映射,但它只告诉每个映射在每个numa节点上分配了多少页。您无法从/proc
中获得所需的信息。只是想说明一下:如果数组足够大,它将获得自己的映射,然后您可以解析/proc/self/numa\u映射
,找到映射并找出每个numa节点上分配了多少页。如果数组嵌入到预先存在的映射中,则无法确定/proc/PID/numa_映射中列出的页面中有多少与数组所占用的子范围相关。另一个问题是,即使是新的映射有时也会与预先存在的映射合并,从而实现第二种情况。谢谢!使用您的链接,我得到“致命错误:numaif.h:没有这样的文件或目录”。你知道怎么回事吗?好的。我得到了它。glibc中不包括标头,但需要安装libnuma-devel或类似的软件包。