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]); }