我的第一个MPI并行程序

问题描述:

给定一个数字字符串,将其各位累加求和,如果和不是一个一位数,则继续将和的各位累加,直到和是一个一位数为止。

串行程序如下:(就是一个简单的递归调用)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define SIZE 1000
char str[SIZE];

void all_sum(char * str);

int main()
{
	printf("please input a series of number:");
	scanf("%s",str);
	all_sum(str);
	return 0;
	
}

void all_sum(char * str)
{
	int len;
	int i;
	int sum=0;

	len=strlen(str);
	for(i=0;i<len;i++)
	{
		sum+=str[i]-'0';
	}
	if(sum>=10)
	{
		itoa(sum,str,10);
		all_sum(str);
	}
	else
	{
		printf("the result is: %d\n",sum);
		return;
	}

}
并行程序如下:(运行环境:MPICH2 + VC6.0)

#define MPICH_SKIP_MPICXX
#include "mpi.h"
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<malloc.h>

#pragma comment (lib, "mpi.lib")

#define SIZE 1000
#define BUF_SIZE 64
char str[SIZE];//for single processor
char buf[BUF_SIZE+1];//for multiple processors

FILE *fp1;//for single processor
FILE *fp2;//for multiple processors
int flag=1;//to terminate the worker processor

int all_sum(char * str);//calculate the sum of a series of integers until the sum is a single number(such as 5)
int buf_read(char * buf, const char * end);//read a length of char from the file

int main(int argc, char *argv[])
{
	int myid,numprocs;
	int i;
	MPI_Status status;
	MPI_Init(&argc,&argv);
	MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
	MPI_Comm_rank(MPI_COMM_WORLD,&myid);

    if (numprocs == 1) //single processors
	{
		
		char ch;
		int sum;
		fp1=fopen("D:\\Program Files\\Microsoft Visual Studio\\MyProjects\\MPI\\collapse_file\\input.txt","r");
		if(!fp1)
		{
			printf("can not open the file!\n");
			exit(1);
		}

		int count=0;
		while(ch=fgetc(fp1)!='\n')
			count++;
		rewind(fp1);
		fread(str, 1, count, fp1);
		sum=all_sum(str); 
		printf("the result is: %d\n",sum);

    } 
	
	else //multiple processors
	{
		
		int sum=0;
		if (myid == 0) 
		{
			/* Master Process */
			/* read a block of chars to buf */
			int read;
			int allocatedJobs = 0;
			
			int part_sum=0;

			
			fp2=fopen("D:\\Program Files\\Microsoft Visual Studio\\MyProjects\\MPI\\collapse_file\\input.txt","r");
			if(!fp2)
			{
				printf("can not open the file!\n");
				exit(1);
			}
			
		
			/* initial allocation */
			
			for(i = 1; i < numprocs; i++) 
			{
				read= buf_read(buf, buf+BUF_SIZE);//read a block, but if the last read was a short item count, don't try to read again
				if (read)
				{
					/* allocate a job to proc i */
					allocatedJobs++;
				    MPI_Send(buf,read,MPI_CHAR,i,99,MPI_COMM_WORLD);				
				}
              
				else//当模拟的处理器个数很大,而需要处理的数据位数很小时,有些处理器不需要工作,就要考虑如何终止不工作的处理器
				{
					// send a termination signal to terminate the worker
					buf[0]='o';
					MPI_Send(buf,BUF_SIZE,MPI_CHAR,i,99,MPI_COMM_WORLD);
				}
			}
			while(allocatedJobs)
			{
				memset(str,0,SIZE*sizeof(char));
				MPI_Recv(str , 1 , MPI_CHAR , MPI_ANY_SOURCE , 99 , MPI_COMM_WORLD , &status);
				part_sum=atoi(str);
				sum+=part_sum;
				

				allocatedJobs--;

				read= buf_read(buf, buf+BUF_SIZE);
				if(read)
				{
					MPI_Send(buf,BUF_SIZE,MPI_CHAR,status.MPI_SOURCE,99,MPI_COMM_WORLD);
					allocatedJobs++;

				}
				else
				{
					// send a termination signal to terminate the worker
					buf[0]='o';
					MPI_Send(buf,BUF_SIZE,MPI_CHAR,status.MPI_SOURCE,99,MPI_COMM_WORLD);
				}


				

			}
		}

		
		else 
		{
			while(flag==1)//之所以要用while循环是考虑到当模拟的处理器个数较小时,每一个模拟的处理器需要多次被分配任务
			{
					MPI_Recv(buf , BUF_SIZE , MPI_CHAR , 0 , 99 , MPI_COMM_WORLD , &status);
				
				
				
					int partitial_sum=0;
				
					char char_partitial_sum;
					partitial_sum=all_sum(buf);
				
					char_partitial_sum=partitial_sum+'0';

					
					if(buf[0]>='0'&&buf[0]<='9')//如果buf[0]为数字字符,则说明本worker processor接收到了master processor分配的任务,则本worker processor
						                        //需要向master processor发送部分和的结果 
						MPI_Send(&char_partitial_sum,1,MPI_CHAR,0,99,MPI_COMM_WORLD);

					
			}

		}

		if (myid == 0) 
		{
			/* print the output */			
			itoa(sum,str,10);
			sum=all_sum(str);
			printf("the result is: %d\n",sum);

		}

	}
	MPI_Finalize();
	return 0;
}

int all_sum(char * str)
{
	int len;
	int i;
	int sum=0;

	len=strlen(str);
	for(i=0;i<len;i++)
	{
		if(str[i]>='0'&&str[i]<='9')
			sum+=str[i]-'0';//将所有的字符转变为数字,然后累加 
		else//如果遇到非数字字符,则置flag为0,结束worker processor
		{
			flag=0;
			break;
		}
	}
	if(sum>=10)//如果和不是一个一位数,则继续将和的各位累加
	{
		itoa(sum,str,10);
		all_sum(str);
	}
	else//直到和是一个一位数
	{
		
		return sum;
	}

}

int buf_read(char * buf, const char * end) 
{
	int count=0;
    count = fread(buf, 1, end - buf, fp2);
    if (count > 0 && buf[count - 1] == '\n') {
        --count;
    }
    return count;
}

input.txt如下:

以不同的模拟处理器个数运行程序结果如下:


写这个并行程序时的最大问题就是master processor和worker processor的通信,master processor怎么将任务分配给各个worker processor,不仅要注意MPI_Send和MPI_Recv数目的严格匹配,还要注意MPI_Send和MPI_Recv里面的参数也要严格匹配。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值