2014-01-28 106 views
0

我正在嘗試使用Parallel.for循環來加速我的過程。我無法完成這項工作,因爲我使用的索引超出了界限。在研究這個網站之後,我想我知道我在做什麼doing wrong,並且我認爲我也以臨時變量的形式找到了解決方案,這些臨時變量在進入代碼中的動作之前存儲了循環變量。然而,這在我的例子中不起作用。我發現有人提供給System.Collections.Concurrent的鏈接,它可以爲像這樣的情況提供安全線程,但我不知道如何使用該集合。我如何去做這件事?在Parallel.for循環中超出範圍

我試圖創建一個複製粘貼代碼爲你們跑,但我做錯事的時候有這可能表明我的經驗不足:

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

    namespace empty 
    { 
     class Program 
     { 
      double[, , ,] info = new double[100, 100, 10, 5]; 

      void calculate() 
      { 
       int row; 
       int layer, tex_class; 
       double result; 
       try 
       { 
        for (row = 0; row < 100; row++) 
        { 
         Parallel.For(0, 99, col => 
         { 
          int tempcol = col; 
          for (layer = 0; layer < 10; layer++) 
          { 
           int templayer = layer; 
           for (tex_class = 0; tex_class < 5; tex_class++) 
           { 
            int tempclass = tex_class; 
            result = info[row, tempcol, templayer, tempclass]; 
           } 
           //other code 
          } 
         }); 
        } 
       } 
       catch { } 
      } 

      static void Main(string[] args) 
      { 
       calculate(); 
      } 
     } 
    } 
+1

哦,我的4維陣列。 –

+1

代碼應該做什麼?我根本不理解它。也許如果你發佈一些預期的輸出...... –

回答

0

我想,你應該使用本地循環變量,因爲您的全局圖層變量會在所有並行線程中增加,就像您的tex_class變量一樣。

類似的東西:

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

namespace empty 
{ 
    class Program 
    { 
     double[, , ,] info = new double[100, 100, 10, 5]; 

     void calculate() 
     { 
      try 
      { 
       for (int row = 0; row < 100; row++) 
       { 
        Parallel.For(0, 99, col => 
        { 
         double result; 
         int tempcol = col; 
         for (int layer = 0; layer < 10; layer++) 
         { 
          int templayer = layer; 
          for (int tex_class = 0; tex_class < 5; tex_class++) 
          { 
           int tempclass = tex_class; 
           result = info[row, tempcol, templayer, tempclass]; 
          } 
          //other code 
         } 
        }); 
       } 
      } 
      catch { } 
     } 

     static void Main(string[] args) 
     { 
      calculate(); 
     } 
    } 
} 

拇指應該是規則,你的局部變量應該是本地的並行裏面的餘地,或者通過某種同步得到保護,否則將被訪問通過幾個線程一次,導致不可預知的行爲。

1

因爲循環並行運行,變量layer和tex_class將在不同的線程中增加。這將導致最終將超過指數的值。確保這些變量的作用域僅在使用變量的循環中。儘可能減少範圍以避免其他線程增加相同的變量。此代碼爲我工作:

class Program 
{ 
    double[, , ,] info = new double[100, 100, 10, 5]; 

    public void calculate() 
    { 
     int row; 
     double result; 
     try 
     { 
      for (row = 0; row < 100; row++) 
      { 
       Parallel.For(0, 99, col => 
       { 
        for (int layer = 0; layer < 10; layer++) 
        { 
         for (int tex_class = 0; tex_class < 5; tex_class++) 
         { 
          result = info[row, col, layer, tex_class]; 
         } 
         //other code 
        } 
       }); 
      } 
     } 
     catch { } 
    } 
} 

除此之外,我建議使用並行上最外環到parallize儘可能多的工作越好。初始化並行會產生開銷,這可能會降低性能而不是增加性能。這是我在這裏做的:

class Program 
    { 
     double[, , ,] info = new double[100, 100, 10, 5]; 

     public void calculate() 
     { 
      double result; 
      try 
      { 
       Parallel.For(0, 100, row => 
       { 
        for (int col = 0; col < 100; col++) 
        { 
         for (int layer = 0; layer < 10; layer++) 
         { 
          for (int tex_class = 0; tex_class < 5; tex_class++) 
          { 
           result = info[row, col, layer, tex_class]; 
          } 
          //other code 
         } 
        } 
       }); 
      } 
      catch { } 
     } 
    }