基於MPI的並行計算—矩陣向量乘


  以前沒接觸過MPI編程,對並行計算也沒什么了解。朋友的期末課程作業讓我幫忙寫一寫,哎,實現結果很一般啊。最終也沒完整完成任務,慚愧慚愧。

  問題大概是利用MPI完成矩陣和向量相乘。輸入:Am×n,Bn×1  ,輸出:Cm×1

  附:程序中定義m=400,n=100,矩陣和向量的取值為隨意整型數,為了便於顯示並行效果,循環完成該計算任務100000次。

實現過程

  1.實驗環境:WINDOWS8.1 64位+ MPICH + VS2013   / kubuntu 14.04 + mpich

  2.解題思路:采用帶狀划分的並行算法,同時用主從結構,設處理器個數為p,對矩陣A按行划分成p塊,每塊含有連續的m行向量,m = N/p,分別存放在標號0...p-1的處理器中,同時將向量B廣播給所有處理器。各處理器並行地進行矩陣向量乘積操作,最后返回結果。

      運行代碼如下:

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

const int rows = 400;  //the rows of matrix
const int cols = 100;  //the cols of matrix

int main(int argc, char* argv[])
{
    int i, j, k, myid, numprocs, anstag;
    int A[rows][cols], B[cols], C[rows];
    int masterpro,buf[cols], ans,cnt;
    double starttime,endtime;
    double tmp,totaltime;

    MPI_Status status;
    masterpro = 0;
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &myid);
    MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
    for(cnt = 0; cnt < 100000; cnt++){        
        if(numprocs < 2){
            printf("Error:Too few processes!\n");
            MPI_Abort(MPI_COMM_WORLD,99);
        }
        if(myid == masterpro){
            starttime = MPI_Wtime();
            for (i = 0; i < cols; i++)
            {
                B[i] = rand()%10;
                for (j = 0; j < rows; j++)
                {
                    A[j][i] = rand()%10;
                }
            }
            //bcast the B vector to all slave processor
            MPI_Bcast(B, cols, MPI_INT, masterpro, MPI_COMM_WORLD);
            //partition the A matrix to all slave processor
            for (i = 1; i < numprocs; i++)
            {
                for (k = i - 1; k < rows; k += numprocs - 1)
                {
                    for (j = 0; j < cols; j++)
                    {    
                        buf[j] = A[k][j];
                    }
                    MPI_Send(buf, cols, MPI_INT, i, k, MPI_COMM_WORLD);
                }
            }
        }
        else{
            //starttime = MPI_Wtime();
            MPI_Bcast(B, cols, MPI_INT, masterpro, MPI_COMM_WORLD);
            //every processor receive the part of A matrix,and make Mul operator with B vector
            for ( i = myid - 1; i < rows; i += numprocs - 1){
                MPI_Recv(buf, cols, MPI_INT, masterpro, i, MPI_COMM_WORLD, &status);
                ans = 0;
        
                for ( j = 0; j < cols; j++)
                {
                    ans += buf[j] * B[j];
                }
                //send back the result
                MPI_Send(&ans, 1, MPI_INT, masterpro, i, MPI_COMM_WORLD);
            }
            //endtime = MPI_Wtime();
            //tmp = endtime-starttime;
        } 
        if(myid == masterpro){    
            //receive the result from all slave processor
            for ( i = 0; i < rows; i++)
            {
                MPI_Recv(&ans, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
            //sender = status.MPI_SOURCE;
                anstag = status.MPI_TAG;
                C[anstag] = ans;
            }
            //print the result
        /*
            for (i = 0; i < rows; i++)
            {
                printf("%d ",C[i]);
                if((i+1)%20 == 0)
                    printf("\n");
            }
        */
        }
    }
    endtime = MPI_Wtime();
    totaltime = endtime-starttime;
    //printf("cost time:%f s.\n",tmp); 
    //MPI_Reduce(&tmp,&totaltime,1,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD);
    if(myid == masterpro)
        printf("total time:%f s.\n",totaltime);
    MPI_Finalize();
    return 0;
}

  測試結果:單機多進程運行時,由於進程資源分配和cpu使用率會隨着進程數增加而減少,所以時間反而會久一點。在linux上測試時,發現2進程運行時,CPU使用率能達100%,4進程運行時平均50%左右。  

  聯機測試過程,還存在一些問題,自己也沒處理好,這里就不誤導大家了。

環境搭建

  Linux環境 kubuntu 14.04 

  (1)安裝:

sudo apt-get install mpd 
sudo apt-get install mpich

   (2)編譯運行

mpicc -o matrixvec matrixvec.c
mpirun -np 2 ./matrixvec

  Windows環境

  主要是MPICH3.1.3+VS2013搭建過程的一些注意問題。

  (1)下載安裝:在MPICH官網下載相應的包,雖然系統是64位,但實際測試過程中,發現64為的mpich3.1.3無法運行,重新安裝32位版本后才正常,所以建議安裝32位版本。同時在環境變量PATH添加mpich/bin的路徑。

  (2)注冊賬號:運行安裝目錄下的/bin/wmpiregister.exe,輸入系統用戶名、密碼。注意,這里注冊的是你在使用的電腦系統的用戶名和密碼。

  

  (3)運行測試:運行安裝目錄下的/bin/wmpiexec.exe,選擇Application為安裝目錄下\examples\cpi.exe(一個計算圓周率的例子程序)

  

  若遇到下例問題,用管理員權限打開控制台,輸入smpd -install即可

  

  下面用VS2013實現簡單的mpi程序作為示例,分享一下配置過程。

  (1)打開VS2013,新建項目及源文件

  

  (2)配置項目屬性,引入mpi頭文件和庫

  因為VC的IO庫與MPI頭文件中的宏定義有沖突,所以需要預定義一個MPICH_SKIP_MPICXX宏,使得預編譯時跳過MPICXX定義,同時可以添加_CRT_SECURE_NO_WARNINGS。

  代碼生成,設置運行庫為多線程,在如下位置選擇“Multi-threaded Debug (/MTd)”,可以通過下拉單選擇

  鏈接器添加連接庫,在如下位置添加“mpi.lib”

  配置完成,通過VS編譯mpi程序,用wmpiexec.exe打開生成的exe文件便可運行,或者用命令行形式。

  

相關參考:

1.MoreWindows Blog:Windows系統下搭建MPI(並行計算)環境

2.Romi-知行合一:Windows下MPI的環境搭建及機群測試


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM