プロセッサ情報の取得
スケーラブルな並列処理を実装する時、プログラムで利用可能なプロセッサ数が取得できれば便利です。実行時ライブラリomp_get_num_procsを使用すればそれが可能です。ただし、注意するべき点があります。それは、ハードアフィニティの機能との関係です。
Windowsには、特定のプロセスやスレッドを特定のCPUで実行するように指定する機能があります。それをハードアフィニティと呼びます。指定しない場合は、WindowsがどのCPUで実行するのかを決定します。こちらの方はソフトアフィニティと呼びます。
OpenMPを使用してもハードアフィニティを使う機会があると考え、その時実行時ライブラリがどのように動作するのか実験しました。
#include <stdio.h> #include <omp.h> #include <Windows.h> #include <process.h> int main(void) { PDWORD_PTR processMask, systemMask; HANDLE processID; /* プログラムで使用可能なプロセッサ数を取得 */ printf( "現時点で利用可能なプロセッサ数は%dです。\n", omp_get_num_procs() ); printf("\n"); /* 現在のアフィニティマスクを取得 */ processID = GetCurrentProcess(); GetProcessAffinityMask( processID, &processMask, &systemMask ); printf( "現時点のプロセスアフィニティマスクは%d, システムアフィニティマスクは%dです。\n", processMask, systemMask); /* 現在のアフィニティマスクを変更 */ SetProcessAffinityMask( processID, 1 ); printf( "ハードアフィニティでCPU0のみ実行可能に変更しました。\n" ); GetProcessAffinityMask( processID, &processMask, &systemMask ); printf( "現時点のプロセスアフィニティマスクは%d, システムアフィニティマスクは%dです。\n", processMask, systemMask); printf("\n"); /* プログラムで使用可能なプロセッサ数を取得 */ printf( "現時点で利用可能なプロセッサ数は%dです。\n", omp_get_num_procs() ); printf( "\n\n\n" ); return 0; }
このプログラムを使用して実行したところ、残念ながらハードアフィニティを設定してもomp_get_num_procs関数が返す値は変化しませんでした。ハードアフィニティを指定するプログラムを書くときにこの点に注意してください。しかしながら、将来この関数の動作は変更されるかもしれませんので十分に注意してください。