2016-04-02 18 views
0

私はマルチスレッド化行列乗算をタスクライトしています。各ベクトル積は新しいスレッドで計算されなければなりません(行列がnでm、mがkであればn個のk個のスレッドが必要です)。また、結果行列の要素の計算順序を示す必要があります。私はコードを書いて奇妙な結果を得ました - 計算の順序はほぼ逐次です。しかし、私は新しいスレッドの各要素を計算するので、結果行列の要素の計算のランダムな順序を取得する必要があります。なにが問題ですか?これは私のコードです。あなたが記述している何C#でのマルチスレッド化行列乗算

using System; 
using System.Threading; 
using System.Collections.Generic; 

namespace MatrixMultiplication 
{ 
class Matrix 
{ 
    public int Row{get; set;} 
    public int Column { get; set;} 
    double[,] arr; 
    Matrix() { } 
    public Matrix(int row,int column) 
    { 
     Row = row; 
     Column = column; 
     arr = new double[row, column]; 
    } 
    public double[] GetColumn(int i) 
    { 
     double[] res=new double[Row]; 
     for (int j = 0; j < Row; j++) 
      res[j] = arr[j, i]; 
     return res; 
    } 
    public double[] GetRow(int i) 
    { 
     double[] res = new double[Column]; 
     for (int j = 0; j < Column; j++) 
      res[j] = arr[i, j]; 
     return res; 
    } 
    public double this[int i,int j] 
    { 
     get { return arr[i, j]; } 
     set { arr[i, j] = value; } 
    } 
    public Matrix RandomValues() 
    { 
     Random rnd=new Random(); 
     for (int i = 0; i < Row; i++) 
      for (int j = 0; j < Column; j++) 
       arr[i, j] =rnd.Next(10); 
     return this; 
    } 

    public void Print() 
    { 
     for(int i=0;i<Row;i++){ 
      for (int j = 0; j < Column; j++) 
       Console.Write(arr[i,j]+" "); 
      Console.WriteLine(); 
     } 
    } 

    public static Matrix operator*(Matrix a, Matrix b) 
    { 
     Matrix result=new Matrix(a.Row,b.Column); 
     List<Thread> threads = new List<Thread>(); 
     for (int i = 0; i <a.Row*b.Column;i++) 
     { 
      int tempi = i; 
      Thread thread = new Thread(()=>VectorMult(tempi, a, b, result)); 
      thread.Start(); 
      threads.Add(thread); 
     } 
     foreach (Thread t in threads) 
      t.Join(); 
     return result; 
    } 

    public static void VectorMult(int tmp, Matrix a, Matrix b,Matrix result){ 
     int i = tmp/b.Column; 
     int j = tmp % b.Column; 
     double[] x = a.GetRow(i); 
     double[] y = b.GetColumn(j); 
     for (int k = 0; k < x.Length; k++) 
      result[i, j] += x[k] * y[k]; 
     Console.WriteLine("Calculate element{0}{1}", i, j); 
    } 
    } 

    class Program 
    { 
    static void Main(string[] args) 
    { 
     int n = int.Parse(Console.ReadLine()); 
     int m = int.Parse(Console.ReadLine()); 
     int k = int.Parse(Console.ReadLine()); 
     Matrix A = new Matrix(n,m).RandomValues(); 
     Matrix B = new Matrix(m,k).RandomValues(); 
     A.Print(); 
     Console.WriteLine(new String('-',20)); 
     B.Print(); 
     Console.WriteLine(new String('-', 20)); 
     Matrix C = A * B; 
     C.Print(); 
    } 
    } 
} 
+0

コースノートを確認してください。示されているコードは、合格グレードを得るために存在する可能性が最も高い同期プリミティブの使用を示していません(正しい結果を得るために実際に気にしなければならないことは間違いありません)。 –

答えて

2

は正常です - 別のスレッドの処理が常に期待されるシーケンスでは動作しない方法を示しています、以前の今日からthis postを参照してください。彼らはずっとやっているかもしれませんが、予期せぬ動作が起こります。

計算は特定のシーケンスで実行する必要がありますか、または発生したシーケンスを確認できるだけで済みますか?

新しいスレッドを開始する場合は、シーケンスを制御することは不可能です。計算の完了と結果の記録(コンソールまたは他の出力)はアトミックな操作ではないため、完了した順序を取得することもできません。

この起こる可能性:Aは

  • 計算Bが
  • 計算Bが
  • 計算Aが
  • 操作マルチスレッドは素晴らしいではありませんが記録されて記録されて終了終了

    1. 計算特定の順序で起こらなければならない。

      ConcurrentQueueに計算結果を挿入できます。シーケンスは、ほとんどはになります。

    +0

    計算されたスレッドの順序を確認する必要があります。そして、私はmutlithreadingなしのプログラムでほぼ同じ入力を得る(私は結果行列の要素のスクリーン番号に印刷する)。しかし、結果行列の要素はランダムな順序で計算されるべきだと私は考えます。 – Vladyslav

    +0

    私が理解していることを確認するには、計算の順序がランダムであるか、ランダムにしたいと言っていますか? –

    +0

    ランダムにしたいです。しかし、私は、異なるスレッドで結果の行列の要素を計算すると、計算の順序はデフォルトでランダムでなければならないと思います。私が間違っている? – Vladyslav