使用MPI消息传递实现hello world的顺序输出

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lusongno1/article/details/82929358

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;
}

我们用若干节点去跑:

lusongno1@ubuntu:~/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号进程……以此类推,一直到最后一个进程打印。很简单的一个程序,但是也有很多细节的地方需要注意……

猜你喜欢

转载自blog.csdn.net/lusongno1/article/details/82929358