C语言 MPI算法练习

来源:互联网 发布:买卖域名赚钱 编辑:程序博客网 时间:2024/05/29 17:25

C语言 MPI算法练习

两个数组a和b, 每个数组大约2000万个数,a[i]=sin(i), b[i]=sin(i+5).

数组描述

数组描述
1. 计算平均值 Mean

平均值
2. 计算标准偏差 Standard deviation

标准偏差
3. 最后计算皮尔森相关系数 Pearson correlation coefficient

皮尔森相关系数

SP.

  1. 普通算法计算出皮尔森相关系数,记录运行时间
  2. MPI算法计算出皮尔森相关系数,记录运行时间
  3. 比较两种算法所花时间,得出速度提升

以下内容仅供参考(新手编程):

“.c” 文件代码:

//#include "stdafx.h"#include "mpi.h"  #include "stdio.h"#include "stdlib.h"#include "string.h"#include "math.h" /*length of array a & b*/int maxArray = 20000000;double serial(),parallel();int main(int argc, char* argv[]){    int rank, numproces;    int namelen;    double t1, t2, t3, serial_resultXY, parallel_resultXY;    /* mpi start*/    MPI_Init(&argc, &argv);    MPI_Comm_rank(MPI_COMM_WORLD, &rank);    MPI_Comm_size(MPI_COMM_WORLD, &numproces);    /*timing point 1*/    t1 = MPI_Wtime();    serial_resultXY=serial(rank,numproces);    /*timing point 2*/    t2 = MPI_Wtime();    parallel_resultXY=parallel(rank,numproces);    /*timing point 3*/    t3 = MPI_Wtime();    if (rank == 0) {        /*out put the result and the time used*/    //  printf("resultX = %f\n", resultA);    //  printf("resultY = %f\n", resultB);        printf("Serial algorithm resultXY = %f\n", serial_resultXY);        printf("Serial algorithm time: %1.2f\n", t2 - t1);         printf("Parallel algorithm resultXY = %f\n", parallel_resultXY);        printf("Parallel algorithm time: %1.2f\n", t3 - t2);         printf("time speedup: %1.2f\n", (t2-t1)-(t3 - t2));        fflush(stdout);    }    /*mpi finish*/    MPI_Finalize();    return 0;}    /*Serial algorithm*/ double serial(int R,int N){    /* initialize elements of array  */    double *a, *b;    int rank=R,numproces=N;    a = (double *)malloc(maxArray * sizeof(double));    b = (double *)malloc(maxArray * sizeof(double));    double sumA = 0, meanA = 0, chaA = 0, resultA = 0, sumB = 0, meanB = 0, chaB = 0, resultB = 0, sumC = 0, resultXY = 0;    /*calculate the the Standard devation number of array a & b*/    for (int i = 0; i < maxArray; i++) {        a[i] = sin(i);        b[i] = sin(i + 5);/* set element at location  */        sumA = sumA + a[i];        sumB = sumB + b[i];        if (i == maxArray - 1)        {            meanA = sumA / maxArray;            meanB = sumB / maxArray;            for (int j = 0; j < maxArray; j++) {                chaA = chaA + (a[j] - meanA)*(a[j] - meanA);                chaB = chaB + (b[j] - meanB)*(b[j] - meanB);                if (j == maxArray - 1)                {                    resultA = sqrt(chaA / maxArray);                    resultB = sqrt(chaB / maxArray);                }            }        }    }    /*calculate the final result*/    if (resultA&&resultB) {        for (int i = 0; i < maxArray; i++) {            sumC = sumC + (a[i] - meanA)*(b[i] - meanB);            if (i == maxArray - 1)            {                double N = maxArray*resultA*resultB;                resultXY = sumC / N;                free(a);                free(b);            }        }    }    /* output process rank, taotal number and name */    printf("***** Process %d of %d on serial algorithm ******\n", rank, numproces);    /*finish timing*/    return resultXY;}/*Parellel*/double parallel(int R,int N){    int rank=R,numproces=N;    /*initialize the length of local array in each process*/    int arrayLength = maxArray / numproces + maxArray % numproces;    double *x, *y;    if (rank == 0) {        /* initialize elements of a & b array  */        x = (double *)malloc(maxArray * sizeof(double));        y = (double *)malloc(maxArray * sizeof(double));        for (int i = 0; i < maxArray; i++) {            x[i] = sin(i);            y[i] = sin(i + 5);        }    }    /*defined 2 arrays*/    double *Na, *Nb;    Na = (double *)malloc(arrayLength * sizeof(double));    Nb = (double *)malloc(arrayLength * sizeof(double));    /*send array a & b from process 0 to all process with the smaller part*/    MPI_Scatter(x, arrayLength, MPI_DOUBLE, Na, arrayLength, MPI_DOUBLE, 0, MPI_COMM_WORLD);    MPI_Scatter(y, arrayLength, MPI_DOUBLE, Nb, arrayLength, MPI_DOUBLE, 0, MPI_COMM_WORLD);    double  sumA = 0, sumB = 0, Global_sumA = 0, Global_sumB = 0, meanA = 0, meanB = 0;    /*calculate the sum of local array in each process*/    for (int i = 0; i < arrayLength; i++) {        sumA += +Na[i];        sumB += +Nb[i];    }    /*calculate the sum of each process and post the result to process rank 0*/    MPI_Reduce(&sumA, &Global_sumA, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);    MPI_Reduce(&sumB, &Global_sumB, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);    meanA = Global_sumA / maxArray;    meanB = Global_sumB / maxArray;    double ExampA = 0, ExampB = 0, ExampAB = 0, Global_exampA = 0, Global_exampB = 0, Global_exampAB = 0;    /*calculate sum in each process*/    for (int i = 0; i < arrayLength; i++) {        ExampA += (Na[i] - meanA)*(Na[i] - meanA);        ExampB += (Nb[i] - meanB)*(Nb[i] - meanB);        ExampAB += (Na[i] - meanA)*(Nb[i] - meanB);    }    /* send the result to process rank 0*/    MPI_Reduce(&ExampA, &Global_exampA, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);    MPI_Reduce(&ExampB, &Global_exampB, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);    MPI_Reduce(&ExampAB, &Global_exampAB, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);    /* free array in every process*/    free(Na);    free(Nb);    double resultX = 0, resultY = 0, resultXY = 0;    /*get the final answer of Standard deviation and Pearson correlation coeffcient*/    resultX = sqrt(Global_exampA / maxArray);    resultY = sqrt(Global_exampB / maxArray);    resultXY = Global_exampAB / (maxArray*resultX*resultY);    /*show how many process and its rank*/    printf("***** Process %d of %d on parallel algorithm ******\n", rank, numproces);    if (rank == 0) {        /*free array in process rank 0*/        free(x);        free(y);        return resultXY;    }}

运行结果:

快0.91秒

有什么不对或者能改进,希望大佬指点

原创粉丝点击