LinuxのC/C++でアフィニティ設定をする方法です!
これをすることで、プロセスが使用するコアを設定することができます。
アフィニティとは?
プロセスをCPUのコアに割り当てる設定。
実行するコアの制限をしたりできます。
各仮想マシンに CPU アフィニティ設定を指定することにより、仮想マシンの割り当てをマルチプロセッサ システム内の使用可能なプロセッサのサブセットに制限できます。
引用: CPU アフィニティの使用
アフィニティの確認方法
tasksetで対象PIDのアフィニティを確認することができます。
$ taskset -pc <PID> pid <PID>'s current affinity list: 0,1
この場合、0と1を使用していることになります。
アフィニティ確認用シェル
毎回PIDを調べてコマンドを叩くのも面倒なので、シェルを作りました。
#!/bin/sh # chk.sh ids=`ps aux | grep ./app | awk '{print $2}'` id=`echo ${ids} | awk '{print $1}'` taskset -pc ${id}
コンパイルの出力を「app」にしているので、プロセスを検索してPIDのアフィニティを出力します。
アフィニティを設定するコード
こんな感じ。
#define _GNU_SOURCE #include <sched.h> #include <iostream> using namespace std; #define CPU0 0x00000000 #define CPU1 0x00000001 int main(void) { string input; cpu_set_t cpu_set; CPU_ZERO(&cpu_set); // マスクを全てOFF CPU_SET(CPU0, &cpu_set); // 設定マスクのコアで実行許可 // CPUアフィニティ設定 int result = sched_setaffinity(0, sizeof(cpu_set_t), &cpu_set); if (result != 0) { cout << "error" << endl; return 1; } cout << "CPU_COUNT: " << CPU_COUNT(&cpu_set) << endl; cout << ">> "; cin >> input; return 0; }
#define _GNU_SOURCEは、必要とネット上に書かれているんですが、コンパイルするとwarningが出ます。
謎い……
CPU_SET()の第1引数を変更することで、設定するCPUが変化します。
ここの設定ごとにチェックしてみます。
実行環境
今回はVirtualBoxにインストールしたUbuntuを使用します。
CPUコア数はデフォルトでは1なので、2にしてあります。
2より大きくすると、「ホストより大きいからダメ!」と怒られるので、2です。
CPU設定ごとの結果
それでは試していきます。
CPU_SET: 0
該当箇所をこのようにします。
CPU_ZERO(&cpu_set); // マスクを全てOFF CPU_SET(0, &cpu_set); // 設定マスクのコアで実行許可 // CPUアフィニティ設定 int result = sched_setaffinity(0, sizeof(cpu_set_t), &cpu_set);
コンソール出力とシェルの実行結果です。
項目 | 値 |
---|---|
CPU数 | 1 |
アフィニティ | 0 |
CPU_SET: 1
該当箇所をこのようにします。
CPU_ZERO(&cpu_set); // マスクを全てOFF CPU_SET(1, &cpu_set); // 設定マスクのコアで実行許可 // CPUアフィニティ設定 int result = sched_setaffinity(0, sizeof(cpu_set_t), &cpu_set);
コンソール出力とシェルの実行結果です。
項目 | 値 |
---|---|
CPU数 | 1 |
アフィニティ | 1 |
CPU_SET: 0, 1
該当箇所をこのように2つにします。
CPU_ZERO(&cpu_set); // マスクを全てOFF CPU_SET(0, &cpu_set); // 設定マスクのコアで実行許可 CPU_SET(1, &cpu_set); // 設定マスクのコアで実行許可 // CPUアフィニティ設定 int result = sched_setaffinity(0, sizeof(cpu_set_t), &cpu_set);
コンソール出力とシェルの実行結果です。
項目 | 値 |
---|---|
CPU数 | 2 |
アフィニティ | 0,1 |
CPU_SET: 4
該当箇所をこのように2つにします。
CPU_ZERO(&cpu_set); // マスクを全てOFF CPU_SET(4, &cpu_set); // 設定マスクのコアで実行許可 // CPUアフィニティ設定 int result = sched_setaffinity(0, sizeof(cpu_set_t), &cpu_set);
すると実行結果は、エラーとなります。
参考
コチラを参考にしました。ありがとうございました。
あとがき
LinuxのC/C++でアフィニティ設定をする方法でした!
アフィニティってものを初めて知りましたが、思ったより簡単に設定できるんですね。