C# WPF并行计算两个矩阵

并行计算两个矩阵

要求:
编写一个WPF应用程序,利用数据并行计算两个矩阵(M×N和N×P)的乘积,得到一个M×P的矩阵。
(1)在代码中用多任务通过调用某方法实现矩阵并行运算,在调用的参数中分别传递M、N、P的大小。
(2)程序中至少要测试3次有代表性的不同大小的矩阵运算,并显示其并行运行用时。

1.初始化矩阵,用100以内的随机数填充

private double[,] Init(int row, int col)
        {
            double[,] data = new double[row, col];
            Random r = new Random();
            for(int i = 0; i < row; i++)
            {
                for(int j = 0; j < col; j++)
                {
                    data[i, j] = r.Next(100);
                }
            }
            return data;
        }

2.串行算法

private void Compute(double[,] a, double[,] b, double[,] result)
        {
            int aRows = a.GetLength(0);
            int aCols = a.GetLength(1);
            int bCols = b.GetLength(1);
            for(int i = 0;i < aRows; i++)
            {
                for (int j = 0; j < bCols; j++)
                {
                    double temp = 0;
                    for (int k = 0; k < aCols; k++)
                    {
                        temp += a[i, k] * b[k, j];
                    }
                    result[i, j] = temp;
                }
            }
            
        }

3.并行算法,仅将最外层换为Parallel.For

private void ParallelCompute(double[,] a, double[,] b, double[,] result)
        {
            int aRows = a.GetLength(0);
            int aCols = a.GetLength(1);
            int bCols = b.GetLength(1);
            Action<int> action = (i) =>
            {
                for (int j = 0; j < bCols; j++)
                {
                    double temp = 0;
                    for (int k = 0; k < aCols; k++)
                    {
                        temp += a[i, k] * b[k, j];
                    }
                    result[i, j] = temp;
                }
            };
            Parallel.For(0, aRows, action);
        }

4.定义时钟,并为防止运行时界面卡顿使用异步编程

Stopwatch stopwatch = new Stopwatch(); 
        public MainWindow()
        {
            InitializeComponent();
        }

        private async void button_Click(object sender, RoutedEventArgs e)
        {
            textblock.Text = "";
            long[] t1 = await Task.Run(() => Multiply(325,18,66));
            textblock.Text = string.Format("测试1(矩阵1:325×18,矩阵2:18×66),非并行用时:{0}毫秒,并行用时:{1}毫秒", t1[0], t1[1]);
            long[] t2 = await Task.Run(() => Multiply(3250, 180, 660));
            textblock.Text += string.Format("\n测试2(矩阵2:3250×180,矩阵2:180×660),非并行用时:{0}毫秒,并行用时:{1}毫秒", t2[0], t2[1]);
            long[] t3 = await Task.Run(() => Multiply(32500, 200, 900));
            textblock.Text += string.Format("\n测试3(矩阵3:32500×200,矩阵2:200×900),非并行用时:{0}毫秒,并行用时:{1}毫秒", t3[0], t3[1]);
        }

5.初始化矩阵后计算,同时计时,结束后返回时钟数组

private long[] Multiply(int m, int n, int p)
        {
            long[] timeElapsed = new long[2];
            double[,] m1 = Init(m, n);
            double[,] m2 = Init(n, p);
            double[,] result = new double[m, p];
            //串行
            stopwatch.Restart();
            result = new double[m, p];
            Compute(m1, m2, result);
            stopwatch.Stop();
            timeElapsed[0] = stopwatch.ElapsedMilliseconds;

            //并行
            stopwatch.Restart();
            result = new double[m, p];
            ParallelCompute(m1, m2, result);
            stopwatch.Stop();
            timeElapsed[1] = stopwatch.ElapsedMilliseconds; 

            return timeElapsed;
        }

结果:
在这里插入图片描述
问题讨论:
1.结果只出现一行,没有用+=。输出未换行,字符串添加\n。
2.初始化时,System.IndexOutOfRangeException:“索引超出了数组界限。”原因:i,j出现写反的错误。
3.仅将最外层的for改为Parallel.For更优。
4.出现数过大,等待时间过久的问题

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值