2

そのため、C コードで MPI を使用してプロセッサ間で情報を送受信する際の通信オーバーヘッドを把握しようとしています。

送信と受信の両方でバッファを渡す必要がありますが、やりたいことは、2 つのプロセッサ間の通信にかかる時間を計ることだけです。

ここに私のコード全体があります:

main(int argc, char** argv){

int n;
int rank;
int time;
int i;
MPI_Status status;

MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);

if(rank == 0){
    n = atoi(argv[1]);
    printf("Size of data set = %d\n", n);
}

MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);

for(i = 0; i < n; i++){
    if(rank == 0){
        MPI_Send(&n, 1, MPI_INT, 1, 0, MPI_COMM_WORLD);
    }

    else{
        MPI_Recv(&n, 1, MPI_INT, 0, 1, MPI_COMM_WORLD, &status);
    }
}

MPI_Barrier(MPI_COMM_WORLD);

time = clock();
printf("Time: %d\n", time);

MPI_Finalize();
}

いくつかのテストを行ったところ、for ループを取り出すと、思いどおりに動作することがわかりました。では、無限ループまたはセグ フォールトのいずれかを引き起こす for ループの何が問題なのでしょうか?

4

4 に答える 4

1

2 つの問題があります。

1)「データセットのサイズ」を受け取ったことを確認するためのコードのチェックはありません。有効なコマンド ライン オプションを指定せずにコードを開始すると、セグメンテーション違反が発生するか、システムによっては予測できない方法で処理が進行します。

2) 送信と受信のタグが一致しません。通信を成功させるには、タグが一致する必要があります。一致するタグがない場合、Recv は一致する送信が見つかるまで待機します。送信は、一致する受信が見つかるまで待機します。

MPI_COMM_WORLD の横にある receive の 1 を 0 に変更すると、コードは正常に実行されます。

于 2011-07-14T16:55:00.430 に答える
1

以下は、あなたが求めていることを行う完全なプログラムです。元のバージョンの動作を妨げるいくつかの問題がありました:

  1. タグが一致しませんでした。これにより、プログラムが停止する可能性があります。
  2. MPI_COMM_WORLD に正確に 2 つの MPI プロセスが含まれているかどうかはチェックされません。これもストールの原因となります。
  3. コマンド ラインに引数が存在しない場合、seg fault が発生する可能性があります。のデフォルト値を追加しましたn
  4. タイミングは有用なものを生成しません。send/recv が実行を開始する前に clock() を呼び出す必要があります。

幸運を!

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <mpi.h>

#define TAG_NUMBER 777     // just something
#define DEFAULT_N 10000000 // takes ~3 seconds on my laptop


int main(int argc, char **argv)
{
  int i,n,rank,size,message=0;
  clock_t start = clock();
  MPI_Status status;

  MPI_Init(&argc, &argv);
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  MPI_Comm_size(MPI_COMM_WORLD, &size);

  // This test assumes two processes in MPI_COMM_WORLD
  // ---------------------------------------------------------------------------
  if (size != 2) {
    if (rank == 0) { // only rank 0 prints
      printf("Please run with exactly 2 processes.\n");
    }
    MPI_Finalize();
    return 1;
  }

  // Collect from the command line the number of messages to send, default to
  // DEFAULT_N.
  // ---------------------------------------------------------------------------
  if (rank == 0) {
    if (argc > 1) {
      n = atoi(argv[1]);
    }
    else {
      n = DEFAULT_N;
    }
    printf("Number of messages to send = %d\n", n);
  }

  // Make sure everyone has the same n.
  MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);

  // ---------------------------------------------------------------------------
  // Here we have ranks 1 and 2 exchange n messages via MPI_Send and MPI_Recv.
  // ---------------------------------------------------------------------------
  for (i=0; i<n; i++) {
    if (rank == 0) {
      MPI_Send(&message, 1, MPI_INT, 1, TAG_NUMBER, MPI_COMM_WORLD);
    }
    else{
      MPI_Recv(&message, 1, MPI_INT, 0, TAG_NUMBER, MPI_COMM_WORLD, &status);
    }
  }

  MPI_Barrier(MPI_COMM_WORLD); // not really necessary
  printf("rank %d: time = %f seconds\n", rank,
     (double)(clock() - start)/CLOCKS_PER_SEC);

  MPI_Finalize();
  return 0;
}
于 2012-02-13T21:59:55.667 に答える
0

正確に 2 つの MPI プロセスを使用しない限り、コードはハングすると思います。

于 2010-03-09T06:58:29.600 に答える
-1

ストリームのベンチマークを試しましたか?

于 2010-03-07T01:38:01.160 に答える