oracular (2) sched_getaffinity.2.gz
名前
sched_setaffinity, sched_getaffinity - スレッドの CPU affinity マスクを設定・取得する
書式
#define _GNU_SOURCE /* feature_test_macros(7) 参照 */ #include <sched.h> int sched_setaffinity(pid_t pid, size_t cpusetsize, const cpu_set_t *mask); int sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask);
説明
スレッドの CPU affinity (親和度) マスクは、そのスレッドが 実行を許可されている CPU の集合 を決定する。 マルチプロセッサシステムでは、CPU affinity マスクを設定することで 性能上のメ リットを得られる可能性がある。 例えば、特定のスレッドを一つの CPU に括り付け (すなわち、そ のスレッドの affinity マスクを一つの CPU に設定し)、 他の全てのスレッドの affinity マスク からその CPU を除外することで、 確実にそのスレッドの実行速度を最大にすることができる。 ま た、あるスレッドの実行を一つの CPU に限定することで、 一つの CPU での実行を停止してから別 の CPU で実行を再開するときに発生する キャッシュ無効化 (cache invalidation) による性能面の 劣化を避けることもできる。 CPU affinity マスクは「CPU の集合」を表す cpu_set_t 構造体で表現され、 cpu_set_t へのポイ ンター mask で指定される。 CPU 集合を操作するためのマクロ群については CPU_SET(3) で記載さ れている。 sched_setaffinity() は、スレッド ID が pid のスレッドの CPU affinity マスクを mask で指定 された値に設定する。 pid が 0 の場合、呼び出し元スレッドが使われる。 cpusetsize 引き数には mask が指すデータの長さ (バイト単位) である。 通常は、この引き数には sizeof(cpu_set_t) を 指定すればよい。 pid で指定されたスレッドが mask で指定された CPU のいずれかで現在実行されていない場合、 そ のスレッドは mask で指定された CPU のいずれかに移動される。 sched_getaffinity() は、 スレッド ID が pid のスレッドの affinity マスクを mask が指す cpu_set_t 構造体に書き込む。 cpusetsize 引き数には mask の (バイト単位の) 大きさを指定す る。
返り値
成功した場合、 sched_setaffinity() と sched_getaffinity() は 0 を返す。 エラーの場合は -1 を返し、 errno を適切に設定する。
エラー
EFAULT 指定されたメモリー番地が不正である。 EINVAL システム上に現在実際に存在し、かつ "cpuset" 機構が課す制限においてそのスレッドに対 して許可されている プロセッサが、 affinity ビットマスク mask に含まれていない。 "cpuset" 機構については cpuset(7) を参照。 EINVAL (sched_getaffinity() と、カーネル 2.6.9 以前の sched_setaffinity()) cpusetsize が カーネルで使われている affinity マスクのサイズより小さい。 EPERM (sched_setaffinity()) 呼び出し元のスレッドに適切な特権がなかった。 呼び出し元 は、実効ユーザー ID が pid で識別されるスレッドの実ユーザー ID または実効ユーザー ID と同じであるか、 CAP_SYS_NICE ケーパビリティ (capability) を持たなければならな い。 ESRCH ID が pid のスレッドが見つからなかった。
バージョン
CPU affinity システムコールは Linux kernel 2.5.8 で導入された。 これらのシステムコールの ラッパー関数は glibc 2.3 で導入された。 最初は、glibc のインターフェースには unsigned int 型の cpusetsize 引き数が入っていた。 glibc 2.3.3 では cpusetsize 引き数が削除された が、glibc 2.3.4 で size_t 型で復活した。
準拠
これらのシステムコールは Linux 固有である。
注意
sched_setaffinity() を呼び出した後は、スレッドが実際に実行される CPU の集合は、 mask 引き 数で指定された集合と、システム上に実際に存在する CPU の集合の 共通集合 (AND) となる。 "cpuset" 機構が使用されている場合には、スレッドが動作する CPU 集合 に対してシステムはさら に制限を加えるかもしれない ("cpuset" 機構については cpuset(7) を参照)。 スレッドが動作す る実際の CPU 集合に対する制限はカーネルにより 暗黙のうちに適用される。 システムで利用可能な CPU 数を判定する方法はいくつかある。 /proc/cpuinfo の内容を調べる、 sysconf(3) を使って _SC_NPROCESSORS_CONF と _SC_NPROCESSORS_ONLN の値を取得する、 /sys/devices/system/cpu/ の CPU ディレクトリの一覧を調べる、などがある。 sched(7) に Linux のスケジューリング方式についての説明がある。 affinity マスクはスレッド単位の属性で、スレッドグループの 各スレッド単位に独立して調整する ことができる。 gettid(2) コールからの返り値をこのコールの pid 引き数として渡すことができ る。 pid に 0 を指定すると呼び出し元のスレッドの属性が設定され、 getpid(2) コールからの返 り値を pid に指定するとスレッドグループのメインスレッドの属性が設定される (POSIX スレッド API を使用している場合、 sched_setaffinity() の代わりに pthread_setaffinity_np(3) を使用 すること)。 fork(2) 経由で生成された子プロセスは親プロセスの CPU affinity マスクを継承する。 affinity マスクは execve(2) の前後で保存される。 C ライブラリとカーネル ABI の違い このマニュアルページでは CPU affinity コールの glibc インターフェースを 説明している。実際 のシステムコールインターフェースは少し違っており、 実際の実装では CPU 集合は簡単なビットマ スクであるという実状を反映し、 mask の型が unsigned long * となっている。 成功時には、生の sched_getaffinity() システムコール自身は cpumask_t データ型の (バイト単位の) 大きさを返 す。 cpumask_t はカーネル内部で CPU 集合のビットマスクを表現するのに 使われているデータ型 である。
関連項目
lscpu(1), nproc(1), taskset(1), clone(2), getcpu(2), getpriority(2), gettid(2), nice(2), sched_get_priority_max(2), sched_get_priority_min(2), sched_getscheduler(2), sched_setscheduler(2), setpriority(2), CPU_SET(3), pthread_setaffinity_np(3), sched_getcpu(3), capabilities(7), cpuset(7), sched(7)
この文書について
この man ページは Linux man-pages プロジェクトのリリース 3.79 の一部 である。プロジェクト の説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。