私は、行列で配列を乗算する小さなアプリケーションに取り組んでいます。問題なく動作します。アプリケーションの実行時間を測定したいと思っています。各プロセスの個々の実行時間(開始と終了)を見つけることができますが、グローバル時間が必要です。
これは私のコードです:
int main(int argc, char **argv){
int rang, procesus;
MPI_Status statut;
double start, end, max_end = 0, min_start = 10000;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rang);
MPI_Comm_size(MPI_COMM_WORLD, &procesus);
MPI_Barrier(MPI_COMM_WORLD);
start = MPI_Wtime();
printf("Starting time of process n. %d %f\n",rang, start);
if(rang==0){
//Master work
}else{
//slaves work
}
MPI_Barrier(MPI_COMM_WORLD);
end = MPI_Wtime();
printf("Ending time of process n.%d %f\n\n\n",rang, end);
MPI_Finalize();
//Out of the Parallelized task
if(min_start > start){
min_start = start;
printf("New minumum starting time %f\n", min_start);
}
if(max_end < end){
max_end = end;
printf("New maximum ending time %f\n", max_end);
}
if(rang == 0){
printf("Start %f\n", min_start);
printf("End %f\n", max_end);
}
return 0;
}
変数min_startとmax_endを「グローバル」変数として使用して、すべてのプロセスの最大温度と最小温度をキャッチしようとしますが、実行する最後のプロセスの開始時間と終了時間は常に取得されます。終了時間は問題ありませんが、最後のプロセスが最初に開始されなかったため、開始時間が間違っています。私は何が間違っているのですか? MPIですべてのプロセスに本当にグローバル変数を使用できますか?使用できる場合はどうすればよいですか?
それは私が出力として持っているものです
Starting time of process n.2. 0.101562
Ending time of process n.2. 0.105469
New minumum starting time 0.101562
New maximum ending time 0.105469
Starting time of process n.3. 0.058594
Ending time of process n.3. 0.062500
New minumum starting time 0.058594
New maximum ending time 0.062500
Starting time of process n. 4. 0.007812
Ending time of process n. 4. 0.011719
New minumum starting time 0.007812
New maximum ending time 0.011719
Starting time of process n.1. 0.148438
Ending time of process n.1. 0.152344
New minumum starting time 0.148438
New maximum ending time 0.152344
Starting time of process n.0. 0.207031
Ending time of process n.0. 0.210938
New minumum starting time 0.207031
New maximum ending time 0.210938
Start 0.207031
End 0.210938
MPI_Init()
およびMPI_Finalize()
は、並列実行の開始と終了をマークせず、MPI呼び出しが許可される場所の開始と終了のみをマークします。MPIでは、すべてのプロセスは最初から最後まで並行して実行され、グローバルデータを共有しません。
MPI_Reduce()
を使用して、プロセスの最小開始時間と最大終了時間を見つけることができます。
ほとんどの場合、開始時刻と終了時刻を追跡するだけで十分なことがよくありますマスターノード上マスターのみでグローバル実行時間を導出します。
注目に値することの1つは、開始時刻を収集する前にバリアを配置する必要があることです(すべてのノードが続行する準備ができていることを確認するため)、および終了時間の前(すべてのノードが完了していることを確認するため)。
double start, end;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Barrier(MPI_COMM_WORLD); /* IMPORTANT */
start = MPI_Wtime();
/* ... do work ... */
MPI_Barrier(MPI_COMM_WORLD); /* IMPORTANT */
end = MPI_Wtime();
MPI_Finalize();
if (rank == 0) { /* use time on master node */
printf("Runtime = %f\n", end-start);
}
すべてのノードで同じことを行うと、各ノードがMPI_Barrier
呼び出しから戻る速度に応じて、わずかな偏差でほぼ同じ結果が得られます。これは通常、ほとんどの実際の実行に比べて非常に小さい値であり、割り引くことができます。
異なるノードから開始/終了時間を使用して時間を導出しようとすることは努力する価値がなく、MPI_Wtime
が グローバル同期クロック を使用しない場合、間違った答えを与える可能性があります。一部のMPI実装では、同期されたWtimeはサポートされていないことに注意してください(MPI_WTIME_IS_GLOBAL
を確認してください)。