スレッドを作成しCPUを固定して実行(32/64bit)

icon 項目のみ表示/展開表示の切り替え

概要

マルチコアやハイパースレッド(HT)のCPUでシングルスレッドのプログラムを実行すると基本的には各CPUへ均等に割り当てられます。
実行CPUを固定すると、キャッシュやTLB等が有効に使われ実行速度の向上が期待できます。
本プログラムはスレッドを作成し、そのスレッドをCPU1に固定して約10秒実行します。実行には2個以上の論理プロセッサが必要です。

テスト環境

コンパイラ

Visual C++ 2008/2013 Express 32/64bit マルチバイト/UNICODE

実行環境

Windows XP Professional Service Pack 3 32bit(VirtualBox)
Windows 7 Enterprise Service Pack 1 64bit(Sandy Bridge-E)
Windows 8.1 Enterprise 64bit(Arrandale)

プログラムソースの概要

WinMain

CreateThread APIによりスレッドを作成し実行します。
重負荷のtest1関数を呼び出します。
SetThreadAffinityMask APIの第2引数でどのCPUに割り当てるかを指定します。
ビット0がCPU0、ビット1がCPU1といったぐらいにビットごとにCPU番号が決まっており、該当ビットを1にするとそのCPUに割り当てられます。
この例では、1<<1としておりこれは1を1回左へシフトしますので、2となり1ビット目が1となります。
以下に第2引数の例を示します。

0x3 // CPU0 CPU1に割り当て
0x80 // CPU7に割り当て
0xff // CPU0~CPU7に割り当て
1<<7 // CPU7に割り当て
なお、SetThreadAffinityMask APIの第2引数は64bitなので64個以上のCPUは指定することができません。
Sleep APIにより10秒待機します。
end_f変数を1にセットし、スレッドに終了指示を与えます。
WaitForSingleObject APIによりスレッドが終了するまで待機します。
CloseHandle APIによりスレッド作成時に作成されたスタック等のデーターを解放します。

hi_load

コンパイラの最適化によりループが削られないように終了指示用の変数はvolatile属性を付加しています。
end_fが0以外の値の時、スレッドを終了します。

ソースコード


//      作成したスレッドをCPU1に固定して実行 約10秒後に終了させる


#include <windows.h>

volatile int end_f = 0; //      スレッドを終了させるときに0以外に設定

//      重負荷のスレッド

DWORD WINAPI  high_load(LPVOID lp){
        while (end_f == 0);
        return 0;
}

int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow){
        HANDLE h;
        DWORD id;
        h = CreateThread(0, 0, &high_load, 0, 0, &id);
        SetThreadAffinityMask(h, 1 << 1);
        Sleep(10000);
        end_f = 1;
        WaitForSingleObject(h, INFINITE); /* スレッド終了まで待つ */
        CloseHandle(h);
        return 0;
}

実行ファイルとソースファイルのダウンロード