矩阵并行计算
前台界面设计
![]()
资源样式引用
<Application.Resources>
<Style x:Key="LabelStyle" TargetType="Label">
<Setter Property="FontSize" Value="25" />
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Background" Value="AliceBlue" />
</Style>
<Style x:Key="BorderStyle" TargetType="Border">
<Setter Property="Height" Value="35" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Background" Value="AliceBlue" />
</Style>
</Application.Resources>
<DockPanel>
<Label DockPanel.Dock="Top" Content="矩阵并行计算" Style="{StaticResource LabelStyle}"/>
<Border DockPanel.Dock="Bottom" Style="{StaticResource BorderStyle}">
<Button Name="btn_start" Content="开 始" Click="btn_start_Click"
HorizontalAlignment="Center" Padding="10 0 10 0" Width="80"/>
</Border>
<ScrollViewer>
<StackPanel Background="White" TextBlock.LineHeight="20">
<TextBlock Name="textBlock_01" Margin="0 10 0 0" TextWrapping="Wrap"/>
</StackPanel>
</ScrollViewer>
</DockPanel>
后台功能实现
public partial class MainWindow : Window
{
Stopwatch count_time = new Stopwatch();
int c = 0;
public MainWindow()
{
InitializeComponent();
}
向Count方法进行传参,即定义矩阵大小,并对输出进行格式化排版
private async void btn_start_Click(object sender, RoutedEventArgs e)
{
textBlock_01.Text += "\n";
c ++;
long[] t1 = await Task.Run(() => Count(200, 18, 27));
AddInfo("测试"+ c +"(矩阵1:200×18,矩阵2:18×27),用时:{1}毫秒", t1[0], t1[1]);
long[] t2 = await Task.Run(() => Count(2000, 180, 270));
AddInfo("测试"+ c +"(矩阵1:2000×180,矩阵2:180×270),用时:{1}毫秒", t2[0], t2[1]);
long[] t3 = await Task.Run(() => Count(2000, 200, 300));
AddInfo("测试"+ c +"(矩阵1:2000×200,矩阵2:200×300),用时:{1}毫秒", t3[0], t3[1]);
}
进行并行时间的计算
private long[] Count(int m, int n, int p)
{
long[] timeElapsed = new long[2];
//第一个矩阵计算
double[,] j1 = InitializeMatrix(m, n);
//第二个矩阵计算
double[,] j2 = InitializeMatrix(n, p);
//实例化一个新的矩阵
double[,] j3 = new double[m, p];
//计时开始
count_time.Restart();
//向计算方法中传参数进行并行计算
j3 = new double[m, p];
Count_Matrix(j1, j2, j3);
//计时结束
count_time.Stop();
//获取运行时间(ms)
timeElapsed[1] = count_time.ElapsedMilliseconds;
return timeElapsed;
}
并行计算的主要函数,对GetLength进行转到定义便可以知道它的用法
public static void Count_Matrix(double[,] a, double[,] b, double[,] c)
{
// GetLength:
// 摘要:
// 获取一个 32 位整数,该整数表示 System.Array 的指定维中的元素数。
//
// 参数:
// dimension:
// System.Array 的从零开始的维度,其长度需要确定。
//
// 返回结果:
// 一个 32 位整数,它表示指定维中的元素数。
int m1 = a.GetLength(0); //获取第一个矩阵行的长度(元素数)
int n1 = a.GetLength(1); //获取第一个矩阵列的长度
int p1 = b.GetLength(1); //获取第二个矩阵列的长度
Action<int> action =(i) =>
{
for (int j = 0; j < p1; j++)
{
double temp = 0;
for (int k = 0; k < n1; k++)
{
temp += a[i, k] * b[k, j];
}
c[i, j] = temp;
}
};
Parallel.For(0, m1, action);
}
对两个获得的矩阵进行随机分配元素,使其充满
private double[,] InitializeMatrix(int rowCount, int colCount)
{
//随机分配矩阵中元素的大小
double[,] matrix = new double[rowCount, colCount];
Random r = new Random();
for (int i = 0; i < rowCount; i++)
{
for (int j = 0; j < colCount; j++)
{
matrix[i, j] = r.Next(100);
}
}
return matrix;
}
private void AddInfo(string format, params object[] args)
{
textBlock_01.Text += string.Format(format, args) + "\n";
}
}