2014-01-28 105 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 { } 
     } 
    }