117 lines
3.2 KiB
C#
117 lines
3.2 KiB
C#
|
|
|||
|
using System.Diagnostics;
|
|||
|
internal class Program
|
|||
|
{
|
|||
|
private static string[] _resTableColumnsNames = new string[] { "m*m", "1 t", "2 t", "3 t", "4 t", "5 t", "6 t", "7 t", "8 t" };
|
|||
|
|
|||
|
private static void Main(string[] args)
|
|||
|
{
|
|||
|
Console.WriteLine(string.Join("\t", _resTableColumnsNames));
|
|||
|
|
|||
|
for (int i = 10; i < 10000; i *= 2)
|
|||
|
{
|
|||
|
var a = CreateMatrix(i, i);
|
|||
|
var b = CreateMatrix(i, i);
|
|||
|
|
|||
|
List<long> times = new() { i };
|
|||
|
|
|||
|
for (int j = 1; j <= 8; j++)
|
|||
|
{
|
|||
|
var sw = new Stopwatch();
|
|||
|
sw.Start();
|
|||
|
|
|||
|
MultiplyMatrix(a, b, j);
|
|||
|
|
|||
|
sw.Stop();
|
|||
|
times.Add(sw.ElapsedMilliseconds);
|
|||
|
}
|
|||
|
Console.WriteLine(string.Join("\t", times));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Создаём матрицу случайных элементов
|
|||
|
/// </summary>
|
|||
|
/// <param name="x"></param>
|
|||
|
/// <param name="y"></param>
|
|||
|
/// <returns></returns>
|
|||
|
private static int[,] CreateMatrix(int x, int y)
|
|||
|
{
|
|||
|
var rnd = new Random();
|
|||
|
|
|||
|
var res = new int[y, x];
|
|||
|
|
|||
|
for (int i = 0; i < y; i++)
|
|||
|
{
|
|||
|
for (int j = 0; j < x; j++)
|
|||
|
{
|
|||
|
res[i, j] = rnd.Next(0, 100);
|
|||
|
}
|
|||
|
}
|
|||
|
return res;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Вывести матрицу. Использовался при отладке
|
|||
|
/// </summary>
|
|||
|
/// <param name="mx"></param>
|
|||
|
private static void PrintMatrix(int[,] mx)
|
|||
|
{
|
|||
|
for (int i = 0; i < mx.GetLength(0); i++)
|
|||
|
{
|
|||
|
for (int j = 0; j < mx.GetLength(1); j++)
|
|||
|
{
|
|||
|
Console.Write($"{mx[i, j].ToString("000")}\t");
|
|||
|
}
|
|||
|
Console.WriteLine();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Непосредственно умножение матриц
|
|||
|
/// </summary>
|
|||
|
/// <param name="a"></param>
|
|||
|
/// <param name="b"></param>
|
|||
|
/// <param name="maxTask"></param>
|
|||
|
/// <returns></returns>
|
|||
|
private static int[,] MultiplyMatrix(int[,] a, int[,] b, int maxTask)
|
|||
|
{
|
|||
|
int[,] res = new int[a.GetLength(0), b.GetLength(1)];
|
|||
|
|
|||
|
var semaphore = new SemaphoreSlim(maxTask, maxTask);
|
|||
|
|
|||
|
for (int i = 0; i < a.GetLength(0); i++)
|
|||
|
{
|
|||
|
for (int j = 0; j < b.GetLength(1); j++)
|
|||
|
{
|
|||
|
semaphore.Wait();
|
|||
|
int ci = i;
|
|||
|
int cj = j;
|
|||
|
_ = Task.Run(() =>
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
res[ci, cj] = CalculateElement(a, b, ci, cj);
|
|||
|
}
|
|||
|
finally
|
|||
|
{
|
|||
|
semaphore.Release();
|
|||
|
}
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
semaphore.Wait(maxTask);
|
|||
|
return res;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Вычисление значение одного элемента
|
|||
|
/// </summary>
|
|||
|
/// <param name="a"></param>
|
|||
|
/// <param name="b"></param>
|
|||
|
/// <param name="i"></param>
|
|||
|
/// <param name="j"></param>
|
|||
|
/// <returns></returns>
|
|||
|
private static int CalculateElement(int[,] a, int[,] b, int i, int j)
|
|||
|
=> Enumerable.Range(0, a.GetLength(1)).Sum(k => a[i, k] * b[k, j]);
|
|||
|
}
|