lisz-works

プログラミングと興味を貴方に

Linux C/C++でアフィニティ設定をする方法

【スポンサーリンク】

プログラムのソースコード

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);

すると実行結果は、エラーとなります。

参考

コチラを参考にしました。ありがとうございました。

qiita.com

qiita.com

qiita.com

kazmax.zpp.jp

linuxjm.osdn.jp

あとがき

LinuxのC/C++でアフィニティ設定をする方法でした!

アフィニティってものを初めて知りましたが、思ったより簡単に設定できるんですね。