2016-11-11 450 views
1

对于NUMA机器,Linux提供了系统调用 set_mempolicy,该进程允许进程为内存分配定义其首选NUMA节点。来自不同进程的set_mempolicy

是否有一些类似的功能允许更改另一个正在运行的进程的内存策略?所以像这样set_mempolicy(pid, ...)其中pid对应于不同的运行过程?

请注意,另一个进程(我想更改其内存策略的进程)已经在运行,我无法控制它。所以这样的解决方案:

set_mempolicy(...); 
fork(); // now new process has the same memory policy 

是不是我在找。

回答

1
  1. 创建mems一个cpuset含有所需节点(S),和memory_migrate含有1
  2. 写进程的PID进cpuset的tasks文件

通过该方法的新的分配将被满足根据cpuset的mems配置,当任务被添加到集合时,现有页面将被迁移。

注意:这真的感觉像是一个serverfault Q/A,但是如果它让你感觉更好,你可以用C语言编写你的cpuset管理。

0

由于我假设您无法更改程序,因此实施方法很少。

  1. 实施什么NUMA策略将在用户空间实现。可以在不同的NUMA节点之间移动一个进程的页面。见migratepages。我想你会偶尔跑一次。

  2. 否则,您可以通过gdb进行连接并设置策略。请注意,如果这会影响已分配的页面,我不能100%确定。在此步骤之前,您可能必须运行迁移页面。

创建一个用于设置您的首选NUMA策略的功能:

inject.c

#include "inject.h" 

void inject(){ 
    printf("Changing memory policy\n"); 
    unsigned long nodemask = 1L << 1; 
    set_mempolicy(MPOL_PREFERRED, &nodemask, 3); 
} 

inject.h

#include <stdio.h> 
#include <numaif.h> 
extern void inject(); 

libinject.so

gcc -c -Wall -Werror -lnuma -fPIC inject.c 
gcc -shared -o libinject.so inject.o -lnuma 

**附加到PID和调用您所定义的功能**

gdb -p pid 
(gdb) call __libc_dlopen_mode("/path_to/libinject.so", 0x0002) 
(gdb) call inject() 

我核实,我能够通过/ proc/PID/numa_maps改变NUMA策略(从改变默认偏好:1)但我不太熟悉numa说改变是有效的。

请注意,这是侵入性的过程,希望有一个更简单的选择。