我正在 Linux 机器上编写一个 C 程序,它需要分配一个 10 到 20 GB 的巨大数组。
分配空间后,我想知道哪个核心拥有该数组的哪些页面。“拥有”是指哪个核心负责哪个页面的连贯性。
是否有任何函数或 shell 命令来获取此信息?
注意:我正在使用带有 gcc4.7 的 Debian。
分配内存时,内核通常只分配虚拟内存;内容(RAM 页)仅在第一次访问时填充。如果被驱逐到文件(文件支持的内存映射)或交换(所有其他内存),它们将在驱逐后的下一次访问时重新填充。这意味着进程分配的每一页内存可能不存在(按照惯例,它在第一次访问时会读取为零),在 RAM 中,或者被驱逐(到磁盘或其他非 RAM 存储介质)。
在标准的多核/多 CPU 机器上,“所有权”是基于缓存线确定的,缓存线通常是 2 的小幂,介于 16 和 256 字节之间。每个 CPU “拥有”它最后接触过的高速缓存行。随着进程的运行,CPU和内核运行代码,从而访问代码,发生变化,因此没有固定的“所有者”;它动态变化。此外,管理通常由特定的芯片、内存管理单元或 MMU 完成,而不是由 CPU 运行的代码完成。(现在,MMU 通常集成到 CPU 中。)您可以将进程固定为仅在某些 CPU 内核或多个内核上运行,并基于该猜测哪个 CPU 内核拥有哪个内存。而且我猜一些 MMU 可能有办法报告它给哪个 CPU 内核提供了哪些缓存线——尽管我严重怀疑它在实践中是否可行。
CPU 内核“拥有”内存的整个想法非常奇怪。我认为 Linux 内核本身甚至不会跟踪哪个 CPU 内核最后接触了哪个页面,它当然不会跟踪哪个 CPU 内核最后接触了哪个缓存行。(跟踪会消耗太多 RAM,并且基本上没有任何好处。)
有分布式内核(至少是 Linux 内核的补丁)和其他一些方法来构建一个集群,其中内存和 CPU 分布在多个物理机器上,但对进程来说是统一的——就像它们正在运行一样在单个物理机器上。在这种情况下,可以查询管理端以找出哪个物理节点拥有哪些 CPU 和哪些内存页面。如果这是您的情况,您需要详细描述您正在使用的内核和工具,因为管理工具各不相同。
move_pages()
您可以使用或设置所有权numa_tonode_memory()
。