山本ワールド
Windowsプログラミング
アルゴリズム Vitual C++ 2008/2013によるWin32/Win64 APIレベルのプログラム 基礎 Vitual C++ 2008/2013によるAPIレベルのプログラム(32/64bit) Wix3でインストーラーを作る Visual C++ 2008 Standard Editonによるフォームアプリケーションのプログラム(32/64bit) Vitual C++ 2008 Standard EditonによるAPIレベルのプログラム(32/64bit) Windows 7対応 Visual C++ 2008 ExpressによるAPIレベルのプログラム Visual C++ 2005 ExpressによるAPIレベルのプログラム Visual C++ Versiosn 5 BORLAND C++ Windowsプログラム全般 Excel VBA その他全CPUの使用率を100%にする(32/64bit)
概要
マルチコアやハイパースレッド(HT)のCPUでシングルスレッドのプログラムを実行すると基本的には各CPUへ均等に割り当てられます。
実行CPUを固定すると、キャッシュやTLB等が有効に使われ実行速度の向上が期待できます。
本プログラムは論理CPUの数のスレッドを作成し、そのスレッドを各論理CPUに固定して約10秒実行します。
        
        実行CPUを固定すると、キャッシュやTLB等が有効に使われ実行速度の向上が期待できます。
本プログラムは論理CPUの数のスレッドを作成し、そのスレッドを各論理CPUに固定して約10秒実行します。

テスト環境
コンパイラ
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
GetCPUMax関数により論理CPUの個数を取得します。CreateThread APIにより各スレッドを作成し実行します。
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に割り当て
Sleep APIにより10秒待機します。
end_f変数を1にセットし、スレッドに終了指示を与えます。
WaitForSingleObject APIにより各スレッドが終了するまで待機します。
CloseHandle APIによりスレッド作成時に作成されたスタック等のデーターを解放します。
hi_load
コンパイラの最適化によりループが削られないように終了指示用の変数はvolatile属性を付加しています。end_fが0以外の値の時、スレッドを終了します。
GetCpuMax
GetSystemInfo APIにより論理CPUの個数を取得します。例えば、Core i7-3820の場合、4コアでHT対応なので、論理CPU数は8個となります。
ソースコード
//      全CPUの使用率を100%にする
#include <windows.h>
//      論理CPU数を取得する
int GetCPUMax(void){
        SYSTEM_INFO sys;
        GetSystemInfo(&sys);
        return sys.dwNumberOfProcessors;
}
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;
        int n;
        int cpuMax = GetCPUMax();
        h = new HANDLE[cpuMax];
        id = new DWORD[cpuMax];
        for ( n = 0; n < cpuMax; n++){
                h[n] = CreateThread(0, 0, &high_load, 0, 0, &id[n]);    //      スレッドを作成
                SetThreadAffinityMask(h[n], 1 << n);      //      CPUを固定
        }
        Sleep(10000);
        end_f = 1;
        for (n = 0; n < cpuMax; n++){
                WaitForSingleObject(h[n], INFINITE); /* スレッド終了を待つ */
                CloseHandle(h[n]);
        }
        delete [] h;
        delete [] id;
        return 0;
}
      Copyright (C) 2012 山本ワールド All Rights Reserved.
    
    
  