C++でOpenMPを使用して並列プログラムを作成しています。
omp_set_num_threads()
を使用してプログラム内のスレッド数を制御したいのですが、機能しません。
#include <iostream>
#include <omp.h>
#include "mpi.h"
using namespace std;
int myrank;
int groupsize;
double sum;
double t1,t2;
int n = 10000000;
int main(int argc, char *argv[])
{
MPI_Init( &argc, &argv);
MPI_Comm_rank( MPI_COMM_WORLD, &myrank );
MPI_Comm_size(MPI_COMM_WORLD,&groupsize);
omp_set_num_threads(4);
sum = 0;
#pragma omp for reduction(+:sum)
for (int i = 0; i < n; i++)
sum+= i/(n/10);
cout<<"sum="<<sum<<endl;
cout<<"threads="<<omp_get_num_threads()<<endl;
MPI_Finalize();
return 0;
}
プログラムの出力:
sum = 4.5e+007
threads=1
スレッド数を制御する方法は?
あなたの場合、並列領域外でomp_get_num_threads()
を呼び出すことに加えて、omp_set_num_threads()
を呼び出しても、OpenMPランタイムが指定された数のスレッドを正確に使用することを保証しません。 omp_set_num_threads()
は、環境変数_OMP_NUM_THREADS
_の値をオーバーライドするために使用され、OpenMPがすべての並列に対して生成するスレッドチームのサイズの上限を制御します領域(_OMP_NUM_THREADS
_の場合)またはその後の並列領域(omp_set_num_threads()
の呼び出し後)。動的システムと呼ばれるものがありますが、ランタイムシステムがそれをより適切と判断した場合でも、より少ないスレッドを選択できます。動的チームを無効にするには、omp_set_dynamic(0)
を呼び出すか、環境変数_OMP_DYNAMIC
_をfalse
に設定します。
特定の数のスレッドを強制するには、動的チームを無効にし、omp_set_num_threads()
のいずれかで目的のスレッド数を指定する必要があります。
_omp_set_dynamic(0); // Explicitly disable dynamic teams
omp_set_num_threads(4); // Use 4 threads for all consecutive parallel regions
#pragma omp parallel ...
{
... 4 threads used here ...
}
_
または_num_threads
_ OpenMP句を使用:
_omp_set_dynamic(0); // Explicitly disable dynamic teams
// Spawn 4 threads for this parallel region only
#pragma omp parallel ... num_threads(4)
{
... 4 threads used here ...
}
_
omp_get_num_threads()
関数は、現在、呼び出し元の並列領域を実行しているチーム内であるスレッドの数を返します。並列領域外で呼び出しているため、1
を返します。
omp_get_num_threadsのGCCマニュアル によると:
プログラムomp_get_num_threadsの順次セクションで1を返します
したがって、この:
cout<<"sum="<<sum<<endl;
cout<<"threads="<<omp_get_num_threads()<<endl;
次のようなものに変更する必要があります。
#pragma omp parallel
{
cout<<"sum="<<sum<<endl;
cout<<"threads="<<omp_get_num_threads()<<endl;
}
私が使用するコードは、動的なチームを無効にするというHristoのアドバイスにも従っています。
私は同じ問題に直面していた。解決策は以下のとおりです
[ソースプログラム]> [プロパティ]> [構成プロパティ]> [C/C++]> [言語]を右クリックし、[開くMPサポートフラグをYesに変更...]に変更します。
目的の結果が得られます。
あなたのomp並列コード内にnum_threadsを設定してみてください、それは私のために働いた。これにより、出力は4になります。
#pragma omp parallel
{
omp_set_num_threads(4);
int id = omp_get_num_threads();
#pragma omp for
for (i = 0:n){foo(A);}
}
printf("Number of threads: %d", id);