10

私は 8 つのプロセッサを搭載したマシンを持っています。次のように、コードで OpenMP と MPI を交互に使用したいと考えています。

OpenMP フェーズ:

  • ランク 1 ~ 7 MPI_Barrier で待機
  • ランク 0 は、OpenMP で 8 つのプロセッサーすべてを使用します。

MPI フェーズ:

  • ランク 0 がバリアに達し、すべてのランクがそれぞれ 1 つのプロセッサーを使用する

これまでのところ、私はやった:

  • I_MPI_WAIT_MODE 1 を設定して、ランク 1 ~ 7 がバリア上で CPU を使用しないようにします。
  • omp_set_num_threads(8) をランク 0 に設定して、8 つの OpenMP スレッドを起動します。

それはすべてうまくいきました。ランク 0 は 8 つのスレッドを起動しましたが、すべてが 1 つのプロセッサに制限されています。OpenMP フェーズでは、1 つのプロセッサで実行されているランク 0 から 8 つのスレッドを取得し、他のすべてのプロセッサはアイドル状態です。

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

4

2 に答える 2

14

次のコードは、OpenMP 部分の前に CPU アフィニティ マスクを保存し、それを変更して並列領域の期間中すべての CPU を許可してから、以前の CPU アフィニティ マスクを復元する方法の例を示しています。コードは Linux 固有のものであり、 MPI ライブラリによるプロセスの固定を有効にしないと意味がありません。Intel MPI で に設定することで非アクティブ化されます (4.x のデフォルトはプロセスをピン留めすることです)。--bind-to-core--bind-to-socketmpiexecI_MPI_PINdisable

#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 個の論理プロセッサ) で動作する必要があります。

于 2012-10-30T18:14:11.957 に答える
0

コメントと回答をありがとうございます。大丈夫。それはすべて「PIN」オプションに関するものです。

私の問題を解決するには、次のことを行う必要がありました。

I_MPI_WAIT_MODE=1

I_MPI_PIN_DOMAIN=omp

そのような単純な。これで、すべてのプロセッサがすべてのランクで利用できるようになりました。

オプション

I_MPI_DEBUG=4

各ランクが取得するプロセッサを示します。

于 2012-11-01T18:42:44.627 に答える