マルチコアCPUではプロセス・スレッドが実行されるCPUコアはOSのスケジューラに依存し、状況に応じて別のCPUコア上にコンテキストが移動することがあります。LinuxではCPUアフィニティを設定することで、このような移動を抑制し特定のCPUコア上でのみプロセス・スレッドを(主にパフォーマンス上の問題で)実行することが出来ます。
CPUアフィニティとは
そのスレッドが実行を許可されている論理CPUの集合です。CPUアフィニティはビットマスクで表されます。
例としてCPU0は 0x00000001
, CPU1は 0x00000002
, CPU0,1,3の集合は 0x0000000b
になります。
CPU0は実体はどのCPUコアかというのは cat /proc/cpuinfo
で確認できます。
コマンドによるCPUアフィニティの設定方法
tasksetというコマンドでプロセスのCPUアフィニティを設定できます。
# taskset -p mask pid
maskにはCPUアフィニティを、pidは変更したいプロセスを指定します。
プロセスpidのスレッド全てに対して変更する場合は -a
オプションを使います。
# taskset -a -p mask pid
あるCPUプロセッサで特定のプロセスのみ実行する方法
そのプロセスのみ、該当のCPUで実行を許可し、他のすべてのプロセスは許可をはずします。
# ps -e -o pid= | xargs -n 1 taskset -p 0xFFFFFFFE
# taskset -p 0x00000001 PID
プログラム上でCPUアフィニティを設定する方法
プログラム上でCPUアフィニティを設定する場合はsched_setaffinity()という関数を使います。
#define _GNU_SOURCE /* feature_test_macros 参照 */
#include <sched.h>
void
func(void)
{
cpu_set_t mask;
int ret;
// mask を全て OFF にする
CPU_ZERO(&mask);
// CPU_AFFINITY_MASKのコアでの実行を許可する
CPU_SET(CPU_AFFINITY_MASK, &mask);
// CPUアフィニティを設定
ret = sched_setaffinity(0, sizeof(mask), &mask);
if (ret != 0) {
// error
}
}