如何在任务中进行矩阵乘法

时间:2016-11-16 23:25:00

标签: c# asynchronous task

我无法在任务中获取矩阵的产品以便运行它 在几个例子中。我认为任务没有正确地进行乘法并调用几个0。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _010029428_Multiplicacion
{
    class Program
    {
        static void Main(string[] args)
        {

        int i, j, m, n;
        Random rnd = new Random((int)DateTime.Now.Ticks & 0x000fff);
        Console.WriteLine("Ingrese el numero de renglones y columnas: ");
        m = Convert.ToInt32(Console.ReadLine());
        n = Convert.ToInt32(Console.ReadLine());
        int[,] a = new int[m, n];
        Console.WriteLine("first Matrix");
        for (i = 0; i < m; i++)
        {
            for (j = 0; j < n; j++)
            {
                a[i, j] = rnd.Next(1, 4);
            }
        }
        Console.WriteLine("First matrix is: ");
        for (i = 0; i < m; i++)
        {
            for (j = 0; j < n; j++)
            {
                Console.Write(a[i, j] + "\t");
            }
            Console.WriteLine();
        }
        int[,] b = new int[m, n];
        Console.WriteLine("Second Matrix: ");
        for (i = 0; i < m; i++)
        {
            for (j = 0; j < n; j++)
            {
                b[i, j] = rnd.Next(1, 4);
            }
        }
        Console.WriteLine("The second matrix is:");
        for (i = 0; i < n; i++)
        {
            for (j = 0; j < n; j++)
            {
                Console.Write(b[i, j] + "\t");
            }
            Console.WriteLine();
        }

        Console.WriteLine("The result is :");
        int[,] c = new int[m, n];
        var multiplicacion = new Task(() =>
        {
            for (j = 0; j < n; j++)
            {
                c[i, j] = 0;
                for (int k = 0; k < n; k++)
                {
                    c[i, j] += a[i, k] * b[k, j];
                }
            }
        });

        for (i = 0; i < m; i++)
        {

            multiplicacion.Start();

        }
        for (i = 0; i < m; i++)
        {
            for (j = 0; j < n; j++)
            {
                Console.Write(c[i, j] + "\t");
            }
            Console.WriteLine();
        }

    }
}
}

代码使用multiplicacion.start()以异步方式运行它 不确定问题可能是什么

1 个答案:

答案 0 :(得分:0)

有几个问题。

首先:您不能只创建一个任务并一次多次运行它。必须为“i”的每个值创建新的Task()。

第二:您不能使用全局变量(“j”)并在异步运行的任务中将其变更,而不进行适当的同步。这将导致程序崩溃或错误的结果。如果需要更改它,每个任务必须拥有它自己的(本地)变量(“jj”)。只读变量(i,a,b,c,m,n)通常可以安全使用,但最好将它们作为参数传递。

第三次:在将结果写入屏幕之前,您必须等待所有任务完成。

:异步运行任务会产生很大的性能开销。因此,除非你的矩阵非常庞大(可能至少是行和列的渲染),否则计算几个异步任务的结果可能比主线程上的简单同步计算慢得多。

如何使其工作的示例如下。代码仍然很丑陋而且不是很好,但应该起作用并给你一些进一步改进的起点。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _010029428_Multiplicacion
{
    class Program
    {
        static void Main(string[] args)
        {

            int i, j, m, n;
            Random rnd = new Random((int)DateTime.Now.Ticks & 0x000fff);
            Console.WriteLine("Ingrese el numero de renglones y columnas: ");
            m = Convert.ToInt32(Console.ReadLine());
            n = Convert.ToInt32(Console.ReadLine());
            int[,] a = new int[m, n];
            Console.WriteLine("first Matrix");
            for (i = 0; i < m; i++)
            {
                for (j = 0; j < n; j++)
                {
                    a[i, j] = rnd.Next(1, 4);
                }
            }
            Console.WriteLine("First matrix is: ");
            for (i = 0; i < m; i++)
            {
                for (j = 0; j < n; j++)
                {
                    Console.Write(a[i, j] + "\t");
                }
                Console.WriteLine();
            }
            int[,] b = new int[m, n];
            Console.WriteLine("Second Matrix: ");
            for (i = 0; i < m; i++)
            {
                for (j = 0; j < n; j++)
                {
                    b[i, j] = rnd.Next(1, 4);
                }
            }
            Console.WriteLine("The second matrix is:");
            for (i = 0; i < n; i++)
            {
                for (j = 0; j < n; j++)
                {
                    Console.Write(b[i, j] + "\t");
                }
                Console.WriteLine();
            }

            Console.WriteLine("The result is :");
            int[,] c = new int[m, n];

            Task[] tasks = new Task[m];
            for (i = 0; i < m; i++)
            {
                var multiplicacion = new Task((parameter) =>
                {
                    int ii = (int)parameter;

                    for (int jj = 0; jj < n; jj++)
                    {
                        c[ii, jj] = 0;
                        for (int k = 0; k < n; k++)
                        {
                            c[ii, jj] += a[ii, k] * b[k, jj];
                        }
                    }
                },
                i);
                tasks[i] = multiplicacion;
                multiplicacion.Start();
            }

            Task.WaitAll(tasks);

            for (i = 0; i < m; i++)
            {
                for (j = 0; j < n; j++)
                {
                    Console.Write(c[i, j] + "\t");
                }
                Console.WriteLine();
            }
            Console.ReadLine();
        }
    }
}