set_mempolicy -
プロセスとその子プロセスの
NUMA メモリの
デフォルトポリシーを設定する
#include <numaif.h>
int set_mempolicy(int mode, unsigned long *nodemask,
unsigned long maxnode);
-lnuma でリンクする。
set_mempolicy()
は、呼び出し元プロセスの
NUMA ポリシーを
policy
に設定する。 NUMA
ポリシーはポリシーモードと
0
個以上のノードから構成され、
設定内容は引き数
mode,
nodemask,
maxnode
により指定される。
NUMA
(非対称メモリアクセス)
マシンでは、CPU により
メモリコントローラが異なり、距離も異なっている。
メモリポリシーは、どのノードからメモリをそのプロセスに
割り当てるかを定めるものである。
set_mempolicy()
は、プロセスのデフォルトポリシーを定める。
プロセスのポリシーは、
mbind(2)
で設定される特定のポリシーにより制御されるメモリ領域以外の
プロセスのアドレス空間におけるページの割り当てに適用される。
プロセスのデフォルトポリシーは、
MAP_PRIVATE
フラグを指定した
mmap(2)
を使ってマップされたメモリマップ・ファイルに対する読み出し専用
(ロードされるだけ)
のページの割り当てにも適用される。
また、
MAP_SHARED
フラグを指定した
mmap(2)
を使ってマップされたメモリマップ・ファイルに対するページの割り当てにも
適用される
(この場合はページのアクセス種別に関わらず適用される)
。
設定したポリシーは、プロセスに新規のページが割り当てられるときにのみ
適用される。無名メモリ
(anonymous memory)
の場合、新規ページの割り当ては
アプリケーションが初めてページにアクセスした際に行われる。
mode 引き数には
MPOL_DEFAULT,
MPOL_BIND,
MPOL_INTERLEAVE,
MPOL_PREFERRED
のいずれか一つを指定してしなければならない。
MPOL_DEFAULT
以外のポリシーの場合、呼び出し元は
nodemask
引き数で一つ以上のノードを指定する必要がある。
mode
引き数には、追加で
モードフラグ
を含めることもできる。
サポートされている
モードフラグ
は以下の通りである。
- MPOL_F_STATIC_NODES (Linux 2.6.26 以降)
- 空でない nodemask
は、物理ノード ID
である。 Linux
では、そのプロセスが異なる
CPU 集合コンテキスト
(cpuset context)
に移動した場合でも、そのプロセスの現在の
CPU
集合コンテキストで
許可されているノード集合が変化した場合でも、
nodemask
をマッピングし直すことはない。
- MPOL_F_RELATIVE_NODES (Linux 2.6.26 以降)
- 空でない nodemask
は、そのプロセスの現在の
CPU
集合で許可されているノード
ID 集合
における相対的なノード
ID である。
nodemask は、最大で
maxnode
ビットから構成されるノード
ID
のビットマスクを指す。
ビットマスクの大きさは、直近の
sizeof(unsigned long)
の倍数に切り上げられるが、カーネルが使用するのは
maxnode
個までのビットだけである。
NULL 値の
nodemask
もしくは値が 0 の
maxnode
はノードの空集合を表す。
maxnode の値が 0 の場合、
nodemask
引き数は無視される。
nodemask
が必須の場面では、
nodemask
に、オンラインで、そのプロセスの現在の
CPU 集合コンテキストで
許可されており (
MPOL_F_STATIC_NODES
モードフラグが指定されていない場合)、メモリがあるノードが
少なくとも一つ入っていなければならない。
mode に
MPOL_F_STATIC_NODES
がセットされ、
nodemask
が必須の場面で、
nodemask
に、そのプロセスの現在の
CPU
集合コンテキストで許可されたノードが
一つも含まれていない場合には、メモリのポリシーとしてデフォルトの
「ローカルから割り当て
(local
allocation)」が適用される。
そのプロセスの CPU
集合コンテキストが
nodemask
で指定されたノードを少なくとも一つ含むようになるまでは、
結果的に指定された動作が上書きされることになる。
MPOL_DEFAULT
モードは、デフォルトではないプロセスのメモリポリシーを削除することを
指定するものである。これにより、メモリポリシーはシステムの
デフォルトポリシーに「戻る」ことになる。
システムのデフォルトポリシーは「ローカルからの割り当て
(local allocation)」、
つまりメモリ割り当てのきっかけとなった
CPU
のノードのメモリが割り当てられる。
nodemask には NULL
を指定しなければならない。
「自ノード (local
node)」に空きメモリが全くない場合、システムは
「近くの (near by)
ノード」からメモリを割り当てようと試みる。
MPOL_BIND
モードは厳密なポリシーで、メモリ割り当ては
nodemask
に指定されたノードに限定される。
nodemask に 2
個以上のノードが指定された場合、ページの割り当ては
ノード ID
が数字として最小のノードから開始され、
そのノードに空きメモリがなくなるまでそのノードから
ページ割り当てが行われる。そのノードに空きメモリがなくなったら、
次に小さなノード ID
を持つノードからページ割り当てが行われる。
これを、
nodemask
で指定された全てのノードで空きメモリがなくなるまで繰り返す。
nodemask
で指定された以外のノードからはページの割り当ては行われない。
MPOL_INTERLEAVE
では、ページ割り当てを
nodemask
に指定されたノードの間でノード
ID
の数字順で交互に行う。
このポリシーでは、複数のノードにページを広げて配置し、これらのページへのメモリ
アクセスを分散することで、遅延ではなく、帯域を最適化する。
ただし、一つのページへのアクセスに関しては依然として一つのノードのメモリ帯域
が上限となる。
MPOL_PREFERRED
は、割り当て時に優先されるノード
(preferred node) を設定する。
カーネルはまず優先ノードからページ割り当てを行おうとし、
優先ノードに空きメモリが少ない場合に「近くの
(near by)」ノードから
割り当てを行う。
nodemask に複数のノード ID
が指定された場合は、
nodemask
内の最初のノードが優先ノードとして選択される。
引き数
nodemask,
maxnode
で空集合が指定された場合は、ポリシーは
(上述のシステムの
デフォルトポリシーと同様に)
「ローカルからの割り当て」となる。
プロセスのメモリポリシーは
execve(2)
の前後で保持され、
fork(2) や
clone(2)
を使って作成された子プロセスに継承される。
返り値¶
成功すると、
set_mempolicy() は
0
を返す。エラーの場合、-1
を返し、
errno
にエラーを示す値を設定する。
エラー¶
- EFAULT
- nodemask と maxnode
で指定されたメモリ領域の一部または全部が、
呼び出し元がアクセス可能なアドレス空間外を指している。
- EINVAL
- mode が不正である。
mode が MPOL_DEFAULT で、 nodemask
が空ではない。 mode
が MPOL_BIND か MPOL_INTERLEAVE で、
nodemask が空である。
maxnode
で実際に意味があるビット数より多くのビット数が指定された。
nodemask
に、サポートされている最大ノード
ID
より大きいノードが指定された。
nodemask
に、オンラインで、かつそのプロセスの現在の
CPU
集合コンテキストで
許可されているノードが一つも含まれていないか、
メモリを含むノードが一つも指定されていない。
mode 引き数に MPOL_F_STATIC_NODES
と MPOL_F_RELATIVE_NODES
の両方が指定された。
- ENOMEM
- 利用可能なカーネルメモリが十分でなかった。
バージョン¶
set_mempolicy()
システムコールはバージョン
2.6.7 で Linux
カーネルに追加された。
このシステムコールは
Linux 固有である。
ページがスワップ・アウトされる場合には、
プロセスポリシーの設定は推奨されない。
スワップ・アウトされたページがページ・インする際にも、
ページ割り当て時に適用されるプロセスポリシーやメモリ領域ポリシーが
使用される。
ライブラリによるサポートについては
numa(7) を参照。
関連項目¶
get_mempolicy(2),
getcpu(2),
mbind(2),
mmap(2),
numa(3),
cpuset(7),
numa(7),
numactl(8)
この文書について¶
この man ページは Linux
man-pages
プロジェクトのリリース
3.65 の一部
である。プロジェクトの説明とバグ報告に関する情報は
http://www.kernel.org/doc/man-pages/
に書かれている。