网络应用编程 实验3 矩阵并行计算练习实验

这篇具有很好参考价值的文章主要介绍了网络应用编程 实验3 矩阵并行计算练习实验。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、实验要求

编写一个WPF应用程序,利用数据并行计算两个矩阵(M×N和N×P)的乘积,得到一个M×P的矩阵。

网络应用编程 实验3 矩阵并行计算练习实验

 

具体要求

(1)在代码中用多任务通过调用某方法实现矩阵并行运算,在调用的参数中分别传递M、N、P的大小。

(2)程序中至少要测试3次有代表性的不同大小的矩阵运算,并显示其并行运行用时

二、实验结果展示

网络应用编程 实验3 矩阵并行计算练习实验

 

 

三、实验代码展示

1.xml部分

<Window x:Class="实验报告3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:实验报告3"
        mc:Ignorable="d"
        Title="利用Parallel.For实现矩阵相乘" Height="450" Width="894">
    <Grid Background="AliceBlue">
        <DockPanel>
            <StackPanel DockPanel.Dock="Top">
                <Border BorderThickness="5" Margin="2" BorderBrush="Red" VerticalAlignment="Center">
                    <TextBlock Text="利用数据并行计算两个矩阵(M*N和N*P)的乘积" FontSize="25" FontFamily="微软雅黑" HorizontalAlignment="Center"/>
                </Border>
            </StackPanel>
            <ScrollViewer DockPanel.Dock="Top" Height="335">
                <DockPanel>
                    <StackPanel DockPanel.Dock="Left" Width="105" VerticalAlignment="Center">
                        <Label Content="M值:" Width="60" FontSize="18" Background="AliceBlue" Margin="10"/>
                        <Label Content="N值:" Width="60" FontSize="18" Background="AliceBlue" Margin="10"/>
                        <Label Content="P值:" Width="60" FontSize="18" Background="AliceBlue" Margin="10"/>
                    </StackPanel>

                    <StackPanel DockPanel.Dock="Left" Width="200" VerticalAlignment="Center">
                        <Border BorderThickness="5" Margin="2" BorderBrush="Orange">
                            <TextBox x:Name="t1" Text=""  FontSize="18" Margin="1"/>
                        </Border>

                        <Border BorderThickness="5" Margin="2" BorderBrush="Orange">
                            <TextBox x:Name="t2" Text=""  FontSize="18" Margin="1"/>
                        </Border>

                        <Border BorderThickness="5" Margin="2" BorderBrush="Orange">
                            <TextBox x:Name="t3" Text=""  FontSize="18" Margin="1"/>
                        </Border>
                    </StackPanel>

                    <StackPanel DockPanel.Dock="Right">
                        <TextBlock x:Name="t4" Text="结果显示:" FontSize="18" FontFamily="楷体" Background="Black" Foreground="AliceBlue" Height="331" Width="534"/>
                    </StackPanel>
                </DockPanel>
            </ScrollViewer>
            <Border DockPanel.Dock="Bottom" HorizontalAlignment="Center">
                <Button Content="运行" Width="70" Height="30" Background="BlueViolet" Click="Button_Click"/>
            </Border>
        </DockPanel>
    </Grid>
</Window>

2.cs部分

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace 实验报告3
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        //实验次数
        int x = 0;
        public MainWindow()
        {
            InitializeComponent();
        }

        private async void Button_Click(object sender, RoutedEventArgs e)
        {
            //接收M,N,P
            int aRow, aCol, bCol;

            int.TryParse(t1.Text, out aRow);
            int.TryParse(t2.Text, out aCol);
            int.TryParse(t3.Text, out bCol);
            //形成要用的两个矩阵ab ,里面存储的数是double类型的,当然在额外创建一个矩阵c接收结果
            double[,] a, b, c;

            a = initMatrix(aRow, aCol);
            b = initMatrix(aCol, bCol);
            c = new double[aRow, bCol];
            //进行矩阵并行运算,并计算时间
            long time1 = await Task.Run(() => timeSpan(a, b, c));
            //将实验次数++
            x++;
            //将计算的值在右侧黑色文本框中显示出来
            t4.Text += string.Format("\n测试{0}(矩阵1:{1}*{2},矩阵2:{3}*{4}),用时:{5}毫秒", x, aRow, aCol, aCol, bCol, time1);
        }

        //初始化矩阵
        public double[,] initMatrix(int row, int column)
        {
            Random random= new Random();

            double[,] matrix = new double[row,column];
            for (int i = 0; i < row; i++) 
            {
                for (int j = 0; j < column; j++) 
                {
                    matrix[i,j] = random.Next(100);
                }
            }
            return matrix;
        } 
        //并行矩阵乘法
        public void ParallelMatrixMultiplication(double[,] a, double[,] b, double[,] c) 
        {
            //获取两个矩阵的行列数,因为TryParse好像用不到全局变量里面,所以只能写的这么复杂了
            int aRows = a.GetLength(0);
            int aCols = a.GetLength(1);
            int bCols = b.GetLength(1);
            //计算并输出,但是 数太大 会产生 数组越界异常

            // i是a行,j是b列,k是a列b行
            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];
                    }
                    c[i, j] = temp;
                }
            };
            //action只是定义了一个方法,所以是不是自动运行的,真正运行的代码是下面这行 并行运行代码,这也解释了i的取值是多少的问题
            Parallel.For(0, aRows , action);
        }
        //计算运算时间
        public long timeSpan(double[,] a, double[,] b, double[,]c)
        {
            Stopwatch sw = Stopwatch.StartNew();
            ParallelMatrixMultiplication(a, b, c);
            sw.Stop();
            return sw.ElapsedMilliseconds;
        }
    }
}

四、实验总结

1. 为什么要用panel控件(各种panel控件),明明用了跟没用一样。
   
    答: 简单的说,panel控件是一个容器控件,你可以在上面放置别的控件,当做一个Form用。

            应用程序会尽可能将一个面板中的所有控件分页到同一屏幕上。通过将控件分组到 Panel 控件中,      应用程序还可使用单个命令隐藏或显示一组控件。

            当移动 Panel 控件时,它包含的所有控件也将移动

2. 所以Form是什么意思?
    简单来讲就是Windows窗体应用,创建wpf自动生成的xml界面,也可以独立添加新的。

    官方一点来说就是:
           1.窗体也是对象,窗体类定义了生成窗体的模板,每当实例化一个窗体类,就产生一个窗体

           2.Form类是所有窗体类的基类。

           3.在一个项目中,每个窗体都有自己的Form.cs代码,但所有窗体只有一个启动窗体,核心便是    Program.cs文件里的Main()函数作为程序的主入口点。

3. textbox和textblock的区别
 前者可以编辑,后者不可以。

4. task.Run 其实在读程序时,可以直接读成“运行.....”

5.与界面交互,例如:将结果在界面中显示出来

6. cts = new System.Threading.CancellationTokenSource();
    放在task(任务,cts.token) 用于侦听取消通知

7. 可以直接用int.TryParse(a,out b); 接收文本框中的值

8. Action本身是一种方法,后面必须加分号.
    Action<>是没有返回值,而有没有参数取决于<>有没有值类型,如有int,就是含有一个int型的参数,这时候就可以像for循环里面 int i=0; 随便使用 i 这个参数了。

9.本次实验有个小问题,就是结果数组写错了,写成了a列b列了,一直导致数组越界异常,耽误了两个多小时。。。。。文章来源地址https://www.toymoban.com/news/detail-451501.html

五、书上原码展示

1.xml部分

<Window x:Class="Experiment3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="利用Parallel.For实现矩阵相乘" Height="350" Width="525">
    <DockPanel>
        <Border DockPanel.Dock="Bottom" Background="Beige" Padding="0 5 0 5">
            <Button Name="btnStart" Padding="20 0 20 0" HorizontalAlignment="Center" Content="开始" Click="btnStart_Click"/>
        </Border>
        <ScrollViewer>
            <StackPanel Background="White" TextBlock.LineHeight="30">
                <TextBlock Name="textBlock1" Margin="0 10 0 0" TextWrapping="Wrap"/>
            </StackPanel>
        </ScrollViewer>
    </DockPanel>
</Window>

2.cs部分

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Experiment3
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {

        Stopwatch stopwatch = new Stopwatch();

        public MainWindow()
        {
            InitializeComponent();
        }

        private async void btnStart_Click(object sender, RoutedEventArgs e)
        {
            long[] t1 = await Task.Run(() => Multiply(200, 18, 27));
            textBlock1.Text = string.Format("测试1(矩阵1:200×18,矩阵2:18×27),用时:{1}毫秒", t1[0], t1[1]);

            long[] t2 = await Task.Run(() => Multiply(2000, 180, 270));
            textBlock1.Text += string.Format("\n测试2(矩阵1:2000×180,矩阵2:180×270),用时:{1}毫秒", t2[0], t2[1]);

            long[] t3 = await Task.Run(() => Multiply(3000, 200, 300));
            textBlock1.Text += string.Format("\n测试3(矩阵1:2000×200,矩阵2:200×300),用时:{1}毫秒", t3[0], t3[1]);
        }

        private long[] Multiply(int rowCount, int colCount, int colCount2)//参数分别是M,N,P
        {
            long[] timeElapsed = new long[2];
            //初始化两个矩阵
            double[,] m1 = InitializeMatrix(rowCount, colCount);
            double[,] m2 = InitializeMatrix(colCount, colCount2);
            //乘之后得到的矩阵,这里相当于手动取得
            double[,] result = new double[rowCount, colCount2];

            // 并行,
            //计时开始
            stopwatch.Restart();
            result = new double[rowCount, colCount2];//M*P

            MultiplyMatricesParallel(m1, m2, result);
            //计时结束
            stopwatch.Stop();
            //返回时间
            timeElapsed[1] = stopwatch.ElapsedMilliseconds;
            return timeElapsed;
        }

        #region 并行
        /// <summary>
        /// 计算两个矩阵的乘积
        /// </summary>
        /// <param name="a">矩阵a</param>
        /// <param name="b">矩阵b</param>
        /// <param name="result">相乘的结果</param>
        public static void MultiplyMatricesParallel(double[,] a, double[,] b, double[,] result)
        {
            //如果是64位机,将int改为Int64可提高性能,但修改后将无法在32位机器上运行
            int aRows = a.GetLength(0);//a的行
            int aCols = a.GetLength(1);//a的列,b的行
            int bCols = b.GetLength(1);//b的列

            // 内循环不需要并行
            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);//实际上就是矩阵a每行都单独去运算,最后结果汇总,上面action中的i就是a的行arows,比如第一行去跟b的j列运算,同时第二(i)行野区和b的j列运算
        }
        #endregion

        public static double[,] InitializeMatrix(int rows, int cols)//初始化矩阵
        {
            double[,] matrix = new double[rows, cols];

            Random r = new Random();
            for (int i = 0; i < rows; i++)
            {
                for (int j = 0; j < cols; j++)
                {
                    matrix[i, j] = r.Next(100); //行列对应的数随机设置
                }
            }
            return matrix;
        }
    }
}

到了这里,关于网络应用编程 实验3 矩阵并行计算练习实验的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【网络应用开发】实验1--Servlet技术及应用

    目录 Servlet技术及应用预习报告 一、实验目的 二、实验原理 三、实验预习内容 1. Web页面中都可以使用哪些方式来发送HTTP请求? 2. GET与POST两种请求方式有什么区别?分别适用于什么情况? 3.HTTP响应内容的类型都有哪些?如何设置HTTP响应内容的类型? 4.什么是ServletContext对象

    2024年02月03日
    浏览(43)
  • 高性能计算实验——矩阵乘法基于MPI的并行实现及优化

    熟练掌握MPI编程方法,并将通用矩阵乘法转为MPI并行实现,进一步加深MPI的使用与理解。 进一步熟悉MPI矩阵乘法的实现,学习MPI点对点通信与集合通信的异同点和各自的优缺点,学会比较二者的性能以及各自使用的情形。 学习如何将自己编写的代码改造为标准库函数,供其

    2024年02月03日
    浏览(51)
  • 高并发应用:TCP网络编程

    Socket 很多系统都提供Socket作为TCP网络连接的抽象 Linux- internet domain socket - SOCK_STREAM Linux中Socket以“文件描述符”FD作为标识。 IO模型 IO模型指的是同时操作Socket的方案。 阻塞 非阻塞 多路复用 阻塞IO 同步读写Socket时,线程陷入内核态。 当读写成功后,切换回用户态,继续执行

    2024年03月14日
    浏览(42)
  • 【网络应用开发】实验2--JSP技术及应用(HTTP状态400错误的请求的解决方法)

    目录 JSP技术及应用预习报告 一、实验目的 二、实验原理 三、实验预习内容 JSP技术及应用实验报告 一、实验目的 二、实验要求 三、实验内容与步骤 1. 创建一个名为exp02的Web项目,创建并执行下面JSP页面,文件名为counter. jsp 2. errorPage属性和isErrorPage属性的使用。 高亮重点 

    2023年04月15日
    浏览(37)
  • Linux系统应用编程(五)Linux网络编程(上篇)

    1.两个网络模型和常见协议 (1)OSI七层模型(物数网传会表应) 物理层、数据链路层、网络层、传输层、会话层、表示层、应用层(自下到上) (2)TCP/IP四层模型(网网传应) 网络接口层(链路层)、网络层、传输层、应用层 (3)常见网络协议所属层 2.字节序 (1)两种

    2023年04月25日
    浏览(36)
  • 矩阵逆在网络流中的应用:30个实例

    网络流是一种用于解决各种优化问题的算法,它的核心是通过构建一个有向图来表示问题,然后在这个图上找到一个最大流或最小流。矩阵逆是一种数学方法,可以用于解决一些线性方程组的问题。在这篇文章中,我们将探讨矩阵逆在网络流中的应用,并给出30个实例。 网络

    2024年02月22日
    浏览(38)
  • MPI安装+CentOs6.5多机环境下MPI并行编程+MPI矩阵并行计算(超详细)

    创建多进程,输出进程号和进程数 运行多进程并行例子程序 编程实现大规模向量/矩阵并行计算 1、在开始安装之前,先检查一下是否已经安装好了相应的编译器。 2、安装MPICH之前,首先要在centos6.5上安装c编译器,(进入超级用户)使用指令安装如下: 3、(返回普通用户)

    2024年02月09日
    浏览(38)
  • 网络编程五--自定义应用层协议

    前面回声服务器/客户端介绍了如何通过对收发IO的控制实现回声服务器/客户端。 在服务器端应用层的处理(协议)可以看作是“回声操作”,即回发客户端发来的消息。而在客户端应用层的处理(协议)则只是简单显示服务器回发的内容。 而协议的通俗理解,就是为了完成

    2024年02月03日
    浏览(91)
  • C++中的网络编程和安全性:实现安全的Web应用程序和网络应用程序

    作者:禅与计算机程序设计艺术 《67. C++中的网络编程和安全性:实现安全的Web应用程序和网络应用程序》 1.1. 背景介绍 随着互联网的快速发展,网络应用程序在人们的生活和工作中扮演着越来越重要的角色,网络编程和安全性也成为了现代应用程序的重要组成部分。在网络

    2024年02月16日
    浏览(51)
  • 【计算机网络笔记】网络应用的体系结构

    什么是计算机网络? 什么是网络协议? 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能(1)——速率、带宽、延迟 计算机网络性能(2)——时延带宽积、丢包率、吞吐量/率 计算机网络体系结构概念 OSI参考模型

    2024年02月08日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包