2014-11-25 3 views
0

곱셈 행렬을 원합니다. Parallel.For를 사용할 때 단일 스레드는 다중 스레드보다 느립니다. 그러나 두 개의 스레드를 사용할 때 단일 스레드는 두 개의 스레드보다 빠릅니다. 곱셈 행렬에 두 개의 스레드를 사용하고 싶습니다. 내 오류가 무엇입니까? 나는 이해하지 못한다. 귀하의 답변 주셔서 감사합니다 ..행렬을 이용한 행렬 곱셈

class carp 
{ 
    double[,] a = new double[300, 300]; 
    double[,] b = new double[300, 300]; 
    double[,] c = new double[300, 300]; 
    int indis = 0; 

    public carp(double[,] a, double[,] b, double[,] c,int i) 
    { 
     this.a = a; 
     this.b = b; 
     this.c = c; 
     indis = i; 
    } 
    public void matrixloop() 
    { 
     Thread t1; 
     Thread t2; 
     ThreadStart starter; 
     ThreadStart starter2; 
     int s = a.GetLength(0); 
     for (int i = 0; i < s; i++) 
     { 
      for (int j = 0; j < s; j++) 
      { 

       starter =() => carpı(i,s,j); 
       starter2 =() => carpı(i, s, j+1); 

       t1=new Thread(starter); 
       t2 = new Thread(starter);       
       t1.Start(); 
       t2.Start(); 
       t1.Join(); 
       t2.Join(); 
       j = j + 1;      

      } 
     }    
    } 

    private void carpı(int i, int s, int j) 
    { 
     //multiplication operation 
     double v = 0; 

     for (int k = 0; k < s; k++) 
     { 
      v += a[i, k] * b[k, j]; 
     } 

     c[i, j] = v + 1;    
    }   
} 
+2

당신이 그들 모두를 측정하는 데 사용되는 코드를 공유를 사용하여 원하는 않습니다. Btw 대답은 간단합니다. 각 반복 (매우 비쌉니다)마다 2 개의 새 스레드를 만들어야합니다. 'Paralell.For'는 스레드를 다시 사용합니다. –

+0

스레드를 스스로 제어하려고하기 때문에 Parallel.For를 사용하고 싶지 않습니다. . 이것을 어떻게 만드나요? –

+2

당신은 어떤 종류의 대답을 기대할지는 명확하지 않습니다. 너는 무엇을 의미하니? 이것을 어떻게 만드나요? * 무엇을 만드나요? –

답변

1

이 두 BackgroundWorker 객체

public class MatrixCalc 
{ 
    readonly double[,] a, b, c; 
    readonly int a_rows, a_cols, b_rows, b_cols, c_rows, c_cols; 
    bool result_ok; 
    int thread_count; 
    BackgroundWorker bw1, bw2; 
    AutoResetEvent re; 

    public MatrixCalc(double[,] a, double[,] b, double[,] c) 
    { 
     a_rows=a.GetLength(0); 
     a_cols=a.GetLength(1); 
     b_rows=b.GetLength(0); 
     b_cols=b.GetLength(1); 
     c_rows=c.GetLength(0); 
     c_cols=c.GetLength(1); 
     // keep references of arrays 
     this.a=a; 
     this.b=b; 
     this.c=c; 
    } 

    public void Multiply() 
    { 
     result_ok=false; 
     this.bw1=new BackgroundWorker(); 
     this.bw2=new BackgroundWorker(); 
     this.re=new AutoResetEvent(false); 
     bw1.WorkerSupportsCancellation=true; 
     bw1.DoWork+=new DoWorkEventHandler(bw_DoWork);    
     bw1.RunWorkerCompleted+=new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted); 
     bw1.RunWorkerAsync(0); 
     bw2.WorkerSupportsCancellation=true; 
     bw2.DoWork+=new DoWorkEventHandler(bw_DoWork); 
     bw2.RunWorkerCompleted+=new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted); 
     bw2.RunWorkerAsync(1); 
     re.WaitOne(); 
     re.WaitOne(); 
    } 
    public bool OK { get { return result_ok; } } 
    public void Cancel() 
    { 
     bw1.CancelAsync(); 
     bw2.CancelAsync(); 
     re.WaitOne(); 
     re.WaitOne(); 
    } 

    void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     thread_count--; 
     this.result_ok=(!e.Cancelled)&&(thread_count==0); 
    } 

    void bw_DoWork(object sender, DoWorkEventArgs e) 
    { 
     thread_count++; 
     if(!e.Cancel) 
     { 
      var offset=(int)e.Argument; 
      for(int i=0; i<a_rows; ++i) 
      { 
       // This is the trick. Start from column 0 or 1 
       // and skip over one column. 
       // 
       // Thread 1 Columns : 0,2,4,6,... 
       // Thread 2 Columns: 1,3,5,7,... 
       // 
       for(int j=offset; j<b_cols; ++j, ++j) 
       { 
        var sum =InnerLoop(i, j); 
        lock(c) 
        { 
         c[i, j]=sum; 
        } 
        // Debug.WriteLine("C[{0},{1}]={2}", i, j, sum); 
       } 
      } 
     } 
     re.Set(); 
    } 

    public double InnerLoop(int a_row, int b_col) 
    { 
     double sum=0; 
     for(int i=0; i<a_cols; i++) 
     { 
      sum+=a[a_row, i]*b[i, b_col]; 
     } 
     return sum; 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     const int N=5; 
     double[,] a = new double[N,N], b=new double[N,N], c=new double[N,N]; 
     MatrixCalc calc=new MatrixCalc(a, b, c); 
     // Fill in some values into arrays 
     for(int i=0; i<N; i++) 
     { 
      a[i, i]=1; 
      b[i, i]=1; 
      if(i>0) 
      { 
       b[i, 0]=-i; 
       a[0, i]=i; 
      } 
     } 

     calc.Multiply(); 

     // Debug.WriteLine("Result: {0}", calc.OK); 
    } 
} 
+0

흠, 어떻게 든 충분한 시간을 기다리지 못합니다. 위의 내용은 교육적인 목적으로 만 사용됩니다. – ja72