set_mempolicy -
スレッドとその子スレッドの
NUMA メモリーの
デフォルトポリシーを設定する
#include <numaif.h>
long set_mempolicy(int mode, const 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_LOCAL (詳細は下記参照)
のいずれか一つを指定しなければならない。
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
で指定されたノードを少なくとも一つ含むようになるまでは、
結果的に指定された動作が上書きされることになる。
mode
引数には、以下の値のいずれかひとつを含めなければならない。
- 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
で空集合が指定された場合は、ポリシーは
(上述のシステムの
デフォルトポリシーと同様に)
「ローカルからの割り当て」となる。
-
MPOL_LOCAL (Linux 3.8 以降)
- This mode specifies "local allocation"; the
memory is allocated on the node of the CPU that triggered the allocation
(the "local node"). The nodemask and maxnode
arguments must specify the empty set. If the "local node" is low
on free memory, the kernel will try to allocate memory from other nodes.
The kernel will allocate memory from the "local node" whenever
memory for this node is available. If the "local node" is not
allowed by the process's current cpuset context, the kernel will try to
allocate memory from other nodes. The kernel will allocate memory from the
"local node" whenever it becomes allowed by the process's
current cpuset context.
スレッドのメモリーポリシーは
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
プロジェクトのリリース
5.10
の一部である。プロジェクトの説明とバグ報告に関する情報は
https://www.kernel.org/doc/man-pages/
に書かれている。