KMP_HW_SUBSET および KMP_AFFINITY 環境変数は、プロセッサーにおける OpenMP* ランタイムのハードウェア・スレッドの使用を制御します。これらの環境変数を使用することで、プロセッサーのコアで異なるスレッドの分配を試したり、スレッドをどのようにコアにバインドするかを決定して、アプリケーションに最適な設定を見つけることができます。
KMP_HW_SUBSET 変数はハードウェア・リソースの割り当てを制御し、KMP_AFFINITY 変数はそれらのリソースへ OpenMP* スレッドをバインドする方法を制御します。
KMP_HW_SUBSET 変数は、プログラムで使用されるハードウェア・リソースを制御します。この変数は、使用するソケット数、各ソケットで使用するコア数、および各コアに割り当てるスレッド数を指定します。24 コア、コアあたり 4 ハードウェア・スレッドのシステムについて考えてみます。コアあたり 1 スレッドの場合よりも、コアあたり 2 スレッドのほうがパフォーマンスは向上しますが、コアあたり 3 または 4 スレッドにすると、パフォーマンスは向上することもしないこともあります。この変数でコアあたり 4 スレッドまでのパフォーマンスを測定できます。
例えば、次のように変数を設定することで、24 コアを搭載したシステムで 24、48、72、または最大 96 の OpenMP* スレッドを割り当てた場合の影響が分かります。
割り当てるスレッド数 |
...設定 |
---|---|
24 |
KMP_HW_SUBSET=24c,1t |
48 |
KMP_HW_SUBSET=24c,2t |
72 |
KMP_HW_SUBSET=24c,3t |
96 |
KMP_HW_SUBSET=24c,4t |
この変数と OMP_NUM_THREADS 変数を一緒に使用する場合は注意が必要です。OMP_NUM_THREADS 変数を使用すると、オーバーサブスクリプション/アンダーサブスクリプションが発生します。
KMP_HW_SUBSET でシステムで利用可能なリソースを超えるリソースを指定すると、ランタイムは警告を出力して設定を無視します。例えば、KMP_HW_SUBSET=24c,5t を指定すると、コアごとに 4 ハードウェア・スレッドのシステムでは無視されます。
KMP_AFFINITY 変数は、KMP_HW_SUBSET 変数によって割り当てられたハードウェア・リソースに OpenMP* スレッドをバインドする方法を制御します。この変数は、いくつかのバインドまたはアフィニティー・タイプに設定できますが、プロセッサーで OpenMP* スレッドを実行する場合、推奨するアフィニティー・タイプは次のとおりです。
compact: コア間でシーケンシャルにスレッドを分配します。
scatter: コア間でラウンドロビン方式 (総当り) でスレッドを分配します。最初は 1 コアに 1 スレッド、その後コア間で繰り返し分布します。
次の表は、KMP_HW_SUBSET=2c,3t を指定して、2 コアでコアあたり 3 スレッドを使用する場合のスレッドのコアへのバインド方法を示します。
アフィニティー |
コア 0 の OpenMP* スレッド |
コア 1 の OpenMP* スレッド |
---|---|---|
KMP_AFFINITY=compact |
0、1、2 |
3、4、5 |
KMP_AFFINITY=scatter |
0、2、4 |
1、3、5 |
これらの変数を使用して最適なスレッドの分配とバインドを見つけるには、次の手順を実行します。
これらの環境変数を使用する前に、OpenMP* コードが正しく動作することを確認します。
現在の OpenMP* コードを使用してベースラインを確定し、プロセッサーにスレッドを割り当てた場合のパフォーマンスと比較します。
KMP_HW_SUBSET 変数により、コアあたり 1、2、3、または 4 スレッドを割り当てた場合のパフォーマンスを測定します。
KMP_AFFINITY 変数により、スレッドをコアにバインドした場合のパフォーマンスを測定します。