実行時間をはかってみよう

並列化したけど、どのくらい時間がかかっているか知りたいですよね?その際は実行時間取得関数を使用します。
では、実際にどのくらい実行時間がかかっているかはかってみましょう。

#include<stdio.h>
#include"mpi.h"
#define N 10000000

int main(int argc,char *argv[])
{
        int rank,size;
        int n;★★★
        MPI_Init(&argc,&argv);
        MPI_Comm_rank(MPI_COMM_WORLD,&rank);
        MPI_Comm_size(MPI_COMM_WORLD,&size);
        printf("hello world I'm %d of %d\n",rank,size);
        for( n = 0 ; n < N ; n++ );★★★
        MPI_Finalize();
        return 0;
}

こんなループを追加しました。では実際にコンパイルして実行します。

$ mpicc -o 003-1 003-1.c 
$ mpirun --machinefile ../machinefile ./003-1 
hello world I'm 0 of 3
hello world I'm 1 of 3
hello world I'm 2 of 3

何にも変わりませんね、ここでタイムスタンプ取得関数をいれましょう。

#include<stdio.h>
#include"mpi.h"
#define N 10000000

int main(int argc,char *argv[])
{
        int rank,size;
        int n;
        double start,end;★★★
        MPI_Init(&argc,&argv);
        MPI_Comm_rank(MPI_COMM_WORLD,&rank);
        MPI_Comm_size(MPI_COMM_WORLD,&size);
        printf("hello world I'm %d of %d\n",rank,size);
        start = MPI_Wtime();★★★
        for( n = 0 ; n < N ; n++ );
        end = MPI_Wtime();★★★
        printf("elapsed time = %lf\n",end-start);★★★
        MPI_Finalize();
        return 0;
}

では実行してみましょう。

 mpicc -o 003-2 003-2.c 
$ mpirun --machinefile ../machinefile ./003-2
hello world I'm 0 of 3
elapsed time = 0.000001
hello world I'm 1 of 3
elapsed time = 0.000001
hello world I'm 2 of 3
elapsed time = 0.000001

それらしき実行時間がでました。でもこれだとあまり実行時間が計測されてもわかりません、ちょっとループを二重にしてもうすこし時間がかかるようにしましょう。

#include<stdio.h>
#include"mpi.h"
#define N 10000000
#define M 1000★★★
int main(int argc,char *argv[])
{
        int rank,size;
        int n;
        int m;★★★
        int A[M];★★★
        double start,end;
        MPI_Init(&argc,&argv);
        MPI_Comm_rank(MPI_COMM_WORLD,&rank);
        MPI_Comm_size(MPI_COMM_WORLD,&size);
        printf("hello world I'm %d of %d\n",rank,size);
        start = MPI_Wtime();
        for( n = 0 ; n < N ; n++ )
                for( m = 0 ; m < M ; m++ )★★★
                        A[m]=m;★★★
        end = MPI_Wtime();
        printf("A[%d] = %d elapsed time = %lf\n",M-1,A[M-1],end-start);★★★
        MPI_Finalize();
        return 0;
}
$ mpicc -o 003-3 003-3.c 
$ mpirun --machinefile ../machinefile ./003-3
hello world I'm 0 of 3
hello world I'm 1 of 3
hello world I'm 2 of 3
A[999] = 999 elapsed time = 6.586488
A[999] = 999 elapsed time = 6.585777
A[999] = 999 elapsed time = 6.610866

配列の書き込みをしてそれを読んでいる簡単なプログラムです。
実行時間が約6.6秒でした。
これだけだと面白くないので、すこし並列化効果を見てみましょう。

こういうプログラムに書き換えます。

#include<stdio.h>
#include"mpi.h"
#define N 10000000
#define M 1000
int main(int argc,char *argv[])
{
        int rank,size;
        int n;
        int m;
        int A[M];
        double start,end;
        MPI_Init(&argc,&argv);
        MPI_Comm_rank(MPI_COMM_WORLD,&rank);
        MPI_Comm_size(MPI_COMM_WORLD,&size);
        printf("hello world I'm %d of %d\n",rank,size);
        start = MPI_Wtime();
        for( n = 0 ; n < N / size ; n++ )★★★
                for( m = 0 ; m < M ; m++ )
                        A[m]=m;
        end = MPI_Wtime();
        printf("A[%d] = %d elapsed time = %lf\n",M-1,A[M-1],end-start);
        MPI_Finalize();
        return 0;
}

変えたのはたった一行ですが、実行時間を計測してみましょう。

$ mpicc -o 003-4 ./003-4.c 
$ mpirun --machinefile ../machinefile ./003-4
hello world I'm 0 of 3
hello world I'm 2 of 3
hello world I'm 1 of 3
A[999] = 999 elapsed time = 1.114910
A[999] = 999 elapsed time = 1.114545
A[999] = 999 elapsed time = 1.127540

見事に実行時間が減りました。でもこれだと見づらいですね、rankが0番のマシンだけ実行時間を表示するようにします。

#include<stdio.h>
#include"mpi.h"
#define N 10000000
#define M 1000
int main(int argc,char *argv[])
{
        int rank,size;
        int n;
        int m;
        int A[M];
        double start,end;
        MPI_Init(&argc,&argv);
        MPI_Comm_rank(MPI_COMM_WORLD,&rank);
        MPI_Comm_size(MPI_COMM_WORLD,&size);
        printf("hello world I'm %d of %d\n",rank,size);
        start = MPI_Wtime();
        for( n = 0 ; n < N / size ; n++ )
                for( m = 0 ; m < M ; m++ )
                        A[m]=m;
        end = MPI_Wtime();
        if(rank==0)★★★
                printf("A[%d] = %d elapsed time = %lf\n",M-1,A[M-1],end-start);
        MPI_Finalize();
        return 0;
}

では、実行してみます。

$ mpicc -o 003-5 003-5.c 
$ mpirun --machinefile ../machinefile ./003-5
hello world I'm 0 of 3
hello world I'm 2 of 3
hello world I'm 1 of 3
A[999] = 999 elapsed time = 1.124599

こんなかんじで1個しか実行時間が出ないようになりました。

ついでなので並列化効果をみましょう。
そのためには -np というオプションを使います。

$ mpirun --machinefile ../machinefile -np 1 ./003-5
hello world I'm 0 of 1
A[999] = 999 elapsed time = 3.367257

$ mpirun --machinefile ../machinefile -np 2 ./003-5
hello world I'm 0 of 2
hello world I'm 1 of 2
A[999] = 999 elapsed time = 1.678189

$ mpirun --machinefile ../machinefile -np 3 ./003-5
hello world I'm 0 of 3
hello world I'm 1 of 3
hello world I'm 2 of 3
A[999] = 999 elapsed time = 1.118737

見事に並列化効果が出ていますね。こんな感じで実行していきます。

今回はここまで。

戻る