說到矩陣乘法,最早想到的就是用兩個for循環,循環矩陣A的行再循環矩陣B的列,從而實現矩陣A與B的相乘。算法
(1)下面是串行算法的實現代碼:windows
#include<stdlib.h> #include<stdio.h> typedef struct { int** mat; //指向指針的指針 int row,col; }matrix; void initial(matrix &M,int row,int col) { int i,j = 0; M.mat = (int **)malloc(row*sizeof(int *)); //分配列空間 for (i = 0; i < row; i++) M.mat[i] = (int *)malloc(col*sizeof(int)); //分配行空間 M.row = row; M.col = col; } void initValue(matrix &M, int row, int col) { int i, j; initial(M,row,col); for (i = 0; i < row; i++) { printf("請輸入第%d行的數據:",i); for (j = 0; j < col; j++) scanf("%d",&M.mat[i][j]); } } void Matrix_Multiply(matrix &A,matrix &B,matrix &C) { int i,j,k; for(i=0;i<A.row;i++) { for(j=0;j<B.col;j++) { C.mat[i][j]=0; //矩陣C須要初始化爲0,不然會輸出負值 for(k=0;k<B.row;k++) C.mat[i][j]+=A.mat[i][k]*B.mat[k][j]; } } } void main() { matrix A,B,C; int row_a,col_a,row_b,col_b; printf("請輸入矩陣A的行數,列數:"); scanf("%d,%d",&row_a,&col_a); printf("請輸入矩陣B的行數,列數:"); scanf("%d,%d",&row_b,&col_b); if(row_a<0||col_a<0||row_b<0||col_b<0||col_a!=row_b) printf("輸入數據有誤!"); else { printf("矩陣A初始化\n"); initValue(A,row_a,col_a); printf("矩陣B初始化\n"); initValue(B,row_b,col_b); initial(C,row_a,col_b); Matrix_Multiply(A,B,C); printf("矩陣A*B的結果:\n"); for(int i=0;i<C.row;i++) { for(int j=0;j<C.col;j++) printf("%d ",C.mat[i][j]); printf("\n"); } } }
(2)並行算法採用的是咱們在計算時常用的行列相乘法,即把將A按行(A1 A2......)分配到A.row個處理器上,後是經過B(B1 B2......)的移位從而實現A的每一行與B的每一列相乘,從而實現並行化並行算法的實現代碼:線程
//#include"stdafx.h" #include<stdlib.h> #include<stdio.h> #include<windows.h> typedef struct { int** mat; //指向指針的指針 int row,col; }matrix; typedef struct { int a; //A的行數 int b; //B的列數 }parameter; matrix A,B,C; HANDLE* h=(HANDLE* )malloc(sizeof(HANDLE)*A.row); void initial(matrix &M,int row,int col) { int i,j = 0; M.mat = (int **)malloc(row*sizeof(int *)); //分配列空間 for (i = 0; i < row; i++) M.mat[i] = (int *)malloc(col*sizeof(int)); //分配行空間 M.row = row; M.col = col; } void initValue(matrix &M, int row, int col) { int i, j; initial(M,row,col); for (i = 0; i < row; i++) { printf("請輸入第%d行的數據:",i); for (j = 0; j < col; j++) scanf("%d",&M.mat[i][j]); } } void Multiply(void *n) //i是A的行數 { int i; parameter p=*((parameter *)n); C.mat[p.a][p.b]=0; for(i=0;i<A.col;i++) { C.mat[p.a][p.b]+=A.mat[p.a][i]*B.mat[i][p.b]; } } void Parallel_MatrixMultiply(matrix &A,matrix &B,matrix &C) { int i,j; parameter* p=(parameter* )malloc(sizeof(parameter)*A.row); int *tag=(int* )malloc(sizeof(int)*A.row); for(i=0;i<B.col;i++) tag[i]=i; for(i=0;i<B.col;i++) { for(j=0;j<A.row;j++) { p[j].a=j; p[j].b=tag[(i+j)%A.row]; //B移位的過程 h[j]=CreateThread(NULL, //建立A.row個線程 0, (LPTHREAD_START_ROUTINE)Multiply, &p[j], //不能直接傳i 0, NULL); printf("建立線程\n"); } } } void main() { int row_a,col_a,row_b,col_b; printf("請輸入矩陣A的行數,列數:"); scanf("%d,%d",&row_a,&col_a); printf("請輸入矩陣B的行數,列數:"); scanf("%d,%d",&row_b,&col_b); if(row_a<0||col_a<0||row_b<0||col_b<0||col_a!=row_b) printf("輸入數據有誤!"); else { printf("矩陣A初始化\n"); initValue(A,row_a,col_a); printf("矩陣B初始化\n"); initValue(B,row_b,col_b); initial(C,row_a,col_b); Parallel_MatrixMultiply(A,B,C); WaitForMultipleObjects(A.row,h,TRUE,INFINITE); printf("矩陣A*B的結果:\n"); for(int i=0;i<C.row;i++) { for(int j=0;j<C.col;j++) printf("%d ",C.mat[i][j]); printf("\n"); } }}