《多核程序设计》学习笔记:矩阵乘法并行化

说到矩阵乘法,最先想到的就是用两个for循环,循环矩阵A的行再循环矩阵B的列,从而实现矩阵A与B的相乘。

(1)下面是串行算法的实现代码:

#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");
		}
	}}

 

转载于:https://my.oschina.net/u/2619218/blog/1491137

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值