2012-10-30 21 views
8

私は8台のプロセッサを持つマシンを持っています。OpenMPとMPIハイブリッドプログラム

OpenMPのフェーズ::

  • ランクMPI_Barrier
  • ランク0に1-7待ち時間は、OpenMP
  • ですべての8個のプロセッサを使用しています私はこのような私のコード上でのOpenMPとMPIを使用して交互にしたいです

MPIのフェーズ:

  • ランク0は、バリアに到達し、すべてのランクは、各

はこれまでのところ、私がやった一つのプロセッサを使用します。上の間、1-7位にランクさ

  • セットI_MPI_WAIT_MODE 1そうはCPUを使用していません障壁。
  • omp_set_num_threads(8)をランク0に設定して、8個のOpenMPスレッドを起動します。

すべてが機能しました。ランク0は8つのスレッドを起動しましたが、すべて1つのプロセッサに限定されています。 OpenMP段階では、あるプロセッサでランク0から8つのスレッドが得られ、他のすべてのプロセッサはアイドル状態です。

ランク0で他のプロセッサを使用するようにMPIに指示するにはどうすればよいですか?私はIntel MPIを使用していますが、必要に応じてOpenMPIまたはMPICHに切り替えることができます。

+1

これはちょうどうまくいくと思います。ピン設定が有効になっていませんか? 'I_MPI_PIN'設定を確認してください。 –

+1

プロセスのピン設定が有効になっていることは間違いありません。あなたがそれを無効にすると、あなたのMPIプロセスはもはやコアバウンドにならなくなり、MPIパーツのパフォーマンスは低下するということです。あなたはCPUマスクをプログラマチックに変更することができます - それを保存し、OpenMPフェーズのすべてのプロセッサを許可し、マスクを復元します。 –

答えて

0

コメントと回答ありがとうございました。大丈夫。それはすべての "PIN"オプションについてです。

I_MPI_WAIT_MODE = 1

I_MPI_PIN_DOMAIN = OMP

そのような単純な:

は私の問題を解決するために、私はちょうどに持っていました。すべてのプロセッサがすべてのランクで使用できるようになりました。

オプション各ランクが取得プロセッサー

I_MPI_DEBUG = 4

示します。

+1

あなたがしたのは、プロセスのピン割り当てを効果的に無効にすることです。利用可能なすべてのCPUに固定されたプロセスは、まったく固定されません。 –

13

次のコードは、OpenMP部分の前にCPUアフィニティマスクを保存し、パラレル領域の期間中すべてのCPUを許可して以前のCPUアフィニティマスクを復元する方法を示しています。このコードはLinux特有のもので、MPIライブラリでプロセスピンを有効にしないとになり、Open MPIで--bind-to-coreまたは--bind-to-socketmpiexecに渡すと意味がありません。 無効化I_MPI_PINdisableをインテルMPIに設定してください(デフォルトで4.xはプロセスをピン止めしています)。

#define _GNU_SOURCE 

#include <sched.h> 

... 

cpu_set_t *oldmask, *mask; 
size_t size; 
int nrcpus = 256; // 256 cores should be more than enough 
int i; 

// Save the old affinity mask 
oldmask = CPU_ALLOC(nrcpus); 
size = CPU_ALLOC_SIZE(nrcpus); 
CPU_ZERO_S(size, oldmask); 
if (sched_getaffinity(0, size, oldmask) == -1) { error } 

// Temporary allow running on all processors 
mask = CPU_ALLOC(nrcpus); 
for (i = 0; i < nrcpus; i++) 
    CPU_SET_S(i, size, mask); 
if (sched_setaffinity(0, size, mask) == -1) { error } 

#pragma omp parallel 
{ 
} 

CPU_FREE(mask); 

// Restore the saved affinity mask 
if (sched_setaffinity(0, size, oldmask) == -1) { error } 

CPU_FREE(oldmask); 

... 

また、OpenMPの実行時のピン留め引数を微調整することができます。 GCC/libgompの場合、アフィニティはGOMP_CPU_AFFINITY環境変数によって制御されますが、Intelコンパイラの場合はKMP_AFFINITYです。 OpenMPランタイムが、提供された親和性マスクとプロセスの親和性マスクと交差する場合は、上記のコードを引き続き使用できます。

ちょうど完全を期すために - 、省エネの設定およびWindows上でのアフィニティー・マスクを復元:

#include <windows.h> 

... 

HANDLE hCurrentProc, hDupCurrentProc; 
DWORD_PTR dwpSysAffinityMask, dwpProcAffinityMask; 

// Obtain a usable handle of the current process 
hCurrentProc = GetCurrentProcess(); 
DuplicateHandle(hCurrentProc, hCurrentProc, hCurrentProc, 
       &hDupCurrentProc, 0, FALSE, DUPLICATE_SAME_ACCESS); 

// Get the old affinity mask 
GetProcessAffinityMask(hDupCurrentProc, 
         &dwpProcAffinityMask, &dwpSysAffinityMask); 

// Temporary allow running on all CPUs in the system affinity mask 
SetProcessAffinityMask(hDupCurrentProc, &dwpSysAffinityMask); 

#pragma omp parallel 
{ 
} 

// Restore the old affinity mask 
SetProcessAffinityMask(hDupCurrentProc, &dwpProcAffinityMask); 

CloseHandle(hDupCurrentProc); 

... 

(64個の論理プロセッサまで)単一プロセッサグループで動作するはずです。