1. 程式人生 > >使用MPI訊息傳遞實現hello world的順序輸出

使用MPI訊息傳遞實現hello world的順序輸出

MPI:hello world順序輸出

在跑MPI並行程式時,我們不知道哪個核心前進得快,故而在沒有其他控制的條件下,誰先執行同一條程式碼,是不可知的。
比如說,對於一個輸出“hello world”的程式,如果採用多個節點來跑,列印順序是不定的。下面是一個hellow程式:

/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
/*
 *  (C) 2001 by Argonne National Laboratory.
 *      See COPYRIGHT in top-level directory.
 */

#include <stdio.h>
#include "mpi.h"

int main( int argc, char *argv[] )
{
    int rank;
    int size;
    
    MPI_Init( 0, 0 );
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    printf( "Hello world from process %d of %d\n", rank, size );
    MPI_Finalize();
    return 0;
}

我們用若干節點去跑:

[email protected]:~/Desktop$ mpirun -n 5 ./a.out
Hello world from process 3 of 5
Hello world from process 2 of 5
Hello world from process 4 of 5
Hello world from process 0 of 5
Hello world from process 1 of 5

發現打印出結果的程序順序是不定,那麼如何修改hello world 程式,讓每次螢幕列印輸出結果均按程序號由小到大順序輸出呢?如下:

/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
/*
*  (C) 2001 by Argonne National Laboratory.
*      See COPYRIGHT in top-level directory.
*/

#include <stdio.h>
#include "mpi.h"
#include <math.h>

int main(int argc, char *argv[]) {
	int myrank;
	int size;
	MPI_Status status;
	MPI_Init(0, 0);
	MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
	MPI_Comm_size(MPI_COMM_WORLD, &size);
	int data;
	data = 1;


	if(size==1) {
		printf("Hello world from process %d of %d\n", myrank, size);
		MPI_Finalize();//增強程式的魯棒性
		return 0;
	}


	if (myrank == 0) {
		printf("Hello world from process %d of %d\n", myrank, size);
		MPI_Send(&data, 1, MPI_INT, (myrank + 1) % size ,99, MPI_COMM_WORLD);
	}

	if (myrank >= 1) {
		MPI_Recv(&data, 1, MPI_INT, myrank - 1, 99, MPI_COMM_WORLD, &status);
		printf("Hello world from process %d of %d\n", myrank, size);
		MPI_Send(&data, 1, MPI_INT, (myrank + 1) % size, 99, MPI_COMM_WORLD);
	}
	MPI_Finalize();
	return 0;
}

基本的思想就是利用點對點訊息通訊,首先0號程序列印,併發出一個訊號給1號程序,1號程序收到訊號後,列印,併發出訊號給2號程序……以此類推,一直到最後一個程序列印。很簡單的一個程式,但是也有很多細節的地方需要注意……