《Java高并发程序设计》学习 --5.9 并行模式之并行算法:矩阵乘法

45 篇文章 0 订阅
在矩阵乘法中,第一个矩阵的列数和第二个矩阵的行数必须是相同的。如果需要进行并行计算,一种简单的策略是可以将A矩阵进行水平分割,得到子矩阵A1和A2,B矩阵进行垂直分割,得到子矩阵B1和B2。此时,我们只要分别计算这些子矩阵的乘积,将结果进行拼接,就能得到原始矩阵A和B的乘积。
我们使用ForkJoin框架来实现这个并行矩阵相乘的想法。为了方便矩阵计算,我们使用jMatrces开源软件,作为矩阵计算的工具。其中,使用的主要API如下:
      Matrix:代表一个矩阵
      MatrixOperator.multiply(Matrix, Matrix):矩阵相乘
      Matrix.row():获得矩阵的行数
      Matrix.getSubMatrix():获得矩阵的子矩阵
      MatrixOperator.horizontalConcatenation(Matrix, Matrix):将两个矩阵进行水平连接
      MatrixOperator.verticalConcatenation(Matrix, Matrix):将两个矩阵进行垂直连接
并行算法代码如下:
public class MatrixMulTask extends RecursiveTask<Matrix> {
	public static final int granularity = 3;
	Matrix m1;
	Matrix m2;
	String pos;
	public MatrixMulTask(Matrix m1,Matrix m2,String pos) {
		this.m1 = m1;
		this.m2 = m2;
		this.pos = pos;
	}
	
	@Override
	protected Matrix compute() {
		if(m1.rows() <= MatrixMulTask.granularity || m2.cols()<=MatrixMulTask.granularity) {
			Matrix mRe = MatrixOperator.multiply(m1, m2);
			return mRe;
		} else {
			int rows;
			rows = m1.rows();
			Matrix m11 = m1.getSubMatrix(1, 1, rows/2, m1.cols());
			Matrix m12 = m1.getSubMatrix(rows/2+1, 1, m1.rows(), m1.cols());
			Matrix m21 = m2.getSubMatrix(1, 1, m2.rows(), m12.cols()/2);
			Matrix m22 = m2.getSubMatrix(1, m2.cols()/2+1, m2.rows(), m2.cols());
			
			ArrayList<MatrixMulTask> subTasks = new ArrayList<MatrixMulTask>();
			MatrixMulTask tmp = null;
			tmp = new MatrixMulTask(m11, m21, "m1");
			subTasks.add(tmp);
			tmp = new MatrixMulTask(m11, m22, "m2");
			subTasks.add(tmp);
			tmp = new MatrixMulTask(m12, m21, "m3");
			subTasks.add(tmp);
			tmp = new MatrixMulTask(m12, m22, "m4");
			subTasks.add(tmp);
			for(MatrixMulTask t : subTasks) {
				t.fork();
			}
			Map<String, Matrix> matrixMap = new HashMap<String,Matrix>();
			for(MatrixMulTask t :subTasks) {
				matrixMap.put(t.pos, t.join());
			}
			Matrix tmp1 = MatrixOperator.horizontalConcatenation(matrixMap.get("m1"), matrixMap.get("m2"));
			Matrix tmp2 = MatrixOperator.horizontalConcatenation(matrixMap.get("m3"), matrixMap.get("m4"));
			Matrix reM = MatrixOperator.verticalConcatenation(tmp1, tmp2);
			return reM;
		}
	}
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		ForkJoinPool forkJoinPool = new ForkJoinPool();
		Matrix m1 = MatrixFactory.getRandomMatrix(10, 10, null);
		Matrix m2 = MatrixFactory.getRandomMatrix(10, 10, null);
		MatrixMulTask task = new MatrixMulTask(m1, m2, null);
		ForkJoinTask<Matrix> result = forkJoinPool.submit(task);
		Matrix pr = result.get();
		System.out.println(pr);
	}
}
MatrixMULTask中的成员变量m1和m2表示要相乘的两个矩阵,pos表示这个乘积结果在父矩阵相乘结果中所处的位置,有m1,m2,m3,和m4等四种。先对矩阵进行分割,分割后得到m11、m12、m21和m22等四个任务,并将它们进行子任务的创建。然后计算这些子任务,最后将m1,m2,m3,和m4拼接成新的矩阵作为最终结果。

注:本篇博客内容总结自《 Java 高并发程序设计》

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值