前言
实现目的:
每个偶数序号的进程发一条消息给其右侧的奇数号进程,并由奇数号进程打印改消息,例如总共7个进程,0号发消息给1号并由1号打印,2号发消息给3号并由3号打印,4号发消息给5号并由5号打印,6号则不发消息,因为没有相应的接收进程。
然后编译、排错、执行,并总结学习心得
一、实验原理与提示
MPI程序必须首先#include <mpi.h>。
所有MPI相关的调用都必须位于MPI_Init()和MPI_Finalize()两个MPI函数之间。MPI_Comm_size(MPI_COMM_WORLD,&comm_sz)MPI_Comm_rank(MPI_COMM_WORLD, &my_rank)两个MPI函数调用分别用于获取并行程序中的进程数和当前进程的序号(rank)。典型SPMD的结构如下:
if(my_rank == x)
do something;
else
do other things;
二、实验源代码
代码如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <mpi.h>
const int MAX_STRING = 100;
int main(void) {
char greeting[MAX_STRING];
int comm_sz;
int my_rank;
MPI_Init(NULL, NULL);
MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
if (my_rank != 0) {
sprintf(greeting, "Greetings from process %d of %d!", my_rank, comm_sz);
MPI_Send(greeting, strlen(greeting)+1, MPI_CHAR,0, 0, MPI_COMM_WORLD);
} else {
printf("Greetings from process %d of %d!\n", my_rank, comm_sz);
for (int q = 1; q < comm_sz; q++){
MPI_Recv(greeting, MAX_STRING, MPI_CHAR, q,0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
printf("%s\n", greeting);
}
}
MPI_Finalize();
return 0;
}
emmm,这个还是不是很好内卷一下
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <mpi.h>
const int MAX_STRING = 100;
int main(void) {
char greeting[MAX_STRING];
int comm_sz;
int my_rank;
MPI_Init(NULL, NULL);
MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
int src, dst;
if(my_rank % 2 != 0)
src = my_rank - 1;
else
dst = my_rank + 1;
if (my_rank % 2 != 0) {
MPI_Recv(greeting, MAX_STRING, MPI_CHAR, src, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
printf("Message printed by process %d: %s\n", my_rank, greeting);
} else {
if(dst != comm_sz) {
sprintf(greeting, "Greetings from process %d of %d!", my_rank, comm_sz);
MPI_Send(greeting, strlen(greeting)+1, MPI_CHAR, dst, 0, MPI_COMM_WORLD);
}
}
MPI_Finalize();
return 0;
}
三、实验效果
三、实验遇到的问题以及解决方法
1.对编译的程序没有理解,没有正确的使用自己设置的comm_sz、my_rank两个变量,导致程序出错。
解决方法:阅读相关程序,了解用法,同时自己不断尝试和改进。
2.对实现每个偶数序号的进程发一条消息给其右侧的奇数号进程,并由奇数号进程打印消息的功能时,并没有进一步思考,只是认为通过ifelse语句来区分开来,并没有考虑可能有进程轮空的现象等导致效果没有很好地实现。
解决方法:通过提前增加else语句将,单数进程和偶数进程区分开来,再进入判断语句中进行发送和接受的任务。
总结
并行程序需要注意的点很多,建议初学者先手动跑一遍来确定自己哪里有需要注意的地方,写出伪代码,然后重新在进行程序编写,血泪的教训,之所以写这篇,希望能帮助到后来者。