2017-02-22 76 views
1

初始化的变量我想运行方法Polygonise平行于细胞(它们是独立的)。 如何为单元创建线程,如果它在循环中初始化?线程用于循环

for (int j = 0; j < RowCount - 1; j++) 
    { 
     for (int k = 0; k < ColumnCount - 1; k++) 
     { 
      GridCell currentCell = GetCurrentCell (Slice1, Slice2, j, k); 
      Polygonise (ref Triangles, int isoLevel, GridCell currentCell); 
     } 
    } 

ADDED:我想将它传递给GPU这样的Parallel.For和PLINQ是不恰当的。的问题是:它执行一个长而因为在Poligonise方法许多计算和有许多行和列(循环PARAMS)。该方法的操作速度非常快,但是这样做的循环非常耗时。我需要在这个多线程的逻辑。

+3

'Parallel.For'?并行Linq(* Plinq *)? –

+0

@DmitryBychenko我希望通过它与Cudafy到GPU这样的Parallel.For和PLINQ是不恰当的。问题是为循环计算并行(可能)架构。它执行很长一段时间,因为Poligonise方法中有很多计算。 –

+0

我的意思是,我需要多线程适当这里 –

回答

-1

您可以使用任务的集合。 这是线程的最佳选择。

 List<Task> tasks = new List<Task>(); 
     for (int j = 0; j < RowCount - 1; j++) 
     { 
      for (int k = 0; k < ColumnCount - 1; k++) 
      { 
       GridCell currentCell = GetCurrentCell(Slice1, Slice2, j, k); 

       // Start a new Task and add it to collection 
       tasks.Add(Task.Factory.StartNew(() => 
       { 
        Polygonise(ref Triangles, isoLevel, currentCell); 
       })); 
      } 
     } 

     // Waiting for the completion of all tasks 
     Task.WaitAll(tasks.ToArray()); 

但是你必须要小心。捕获变量并不总是按照您期望的方式工作。 (Literature

+2

如果你建议'任务'执行,你可能意味着'等待Task.WhenAll(任务);'为了不阻止UI(使用'Task's的主要优点) –

+0

可能是这样的。这取决于实施。 –

+2

应避免使用'Task.Factory.StartNew','Task.Run'。看到http://blog.stephencleary.com/2015/03/a-tour-of-task-part-9-delegate-tasks.html为dfetailes –

0

的直截了当的答案是创建它们,你需要他们并没有启动:

for (int j = 0; j < RowCount - 1; j++) 
{ 
    for (int k = 0; k < ColumnCount - 1; k++) 
    { 
     GridCell currentCell = GetCurrentCell (Slice1, Slice2, j, k); 
     System.Threading.Thread t = new System.Threading.Thread(()=> 
     Polygonise (ref Triangles, isoLevel, currentCell)); 
     t.Start(); 
    } 
} 

声明:我不知道什么是Triangles,你怎么可能在你的方法改,所以允许许多线程以无序的方式改变相同的变量可能不明智。

+0

这只是用于一个循环的通道中的一个线程,是不是? P.S.三角形是为细胞。他们也是独立的。没关系。 –

+0

@JuliaGrabovska是的每个迭代它创建一个线程。如果你有一个大矩阵,这是很多。这是否是一种进步,我不能说。你将不得不自己衡量表现。最后你会有(RowCount - 1)*(ColumnCount - 1)线程 –

4

您可以尝试两种Parallel S:

Parallel.For(0, RowCount, (j) => 
{ 
    for (int k = 0; k < ColumnCount - 1; k++) 
    { 
     GridCell currentCell = GetCurrentCell (Slice1, Slice2, j, k); 
     // Beware! Possible race condition: 
     // "ref Triangles" is shared reference between threads. 
     Polygonise (ref Triangles, int isoLevel, GridCell currentCell); 
    } 
}); 

PLINQ(并行LINQ):

Enumerable 
    .Range(0, RowCount) 
    .AsParallel() 
    // .WithDegreeOfParallelism(4) // <- if you want to tune PLinq 
    .ForAll(j => { 
     for (int k = 0; k < ColumnCount - 1; k++) 
     { 
      GridCell currentCell = GetCurrentCell (Slice1, Slice2, j, k); 
      // Beware! Possible race condition: 
      // "ref Triangles" is shared reference between threads. 
      Polygonise (ref Triangles, int isoLevel, GridCell currentCell); 
     } 
    }); 

在这两种情况下,请考虑应并行ColumnsRows

+0

糟糕的例子,因为你开始平行只是'Polygonise'方法的一部分。 –

+2

@Ivan Kishchenko:太多的线程(例如每个单元的线程)通常意味着很大的*开销*;由于CPU内核数量有限('2-32'),更好的策略是创建/获取有限数量的线程(例如每行或每列有一个线程)。不要* overparallelize *。 GPU(例如NVidia'Cuda')是例外(GPU通常具有1000+核心) –

+0

现代处理器能够有效地并行化任务。请打开任务管理器并查看有多少个进程。多少个线程包含任何进程? –